From b46eca4ec61f040f90d4c954c9487197c742e848 Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Tue, 20 Oct 2020 23:51:30 -0400 Subject: [PATCH] Store expeditions with dz id not instance id This exposes dynamic zone ids for any future changes and will make it easier to preserve historic dz and expedition data. This also cleans up some dynamic zone creation for expedition requests When purging instances the expedition table is no longer updated since dynamic zone ids are not re-used like instance ids are Update #dz list commands to show dz id Add GetDynamicZoneID and get_expedition_by_dz_id quest apis --- common/database_instances.cpp | 4 - utils/sql/git/required/wip_expeditions.sql | 4 +- world/expedition.cpp | 8 +- world/expedition.h | 6 +- world/expedition_database.cpp | 69 +++++-------- world/expedition_database.h | 2 +- world/expedition_state.cpp | 2 +- zone/command.cpp | 21 ++-- zone/dynamiczone.cpp | 115 ++++++++------------- zone/dynamiczone.h | 18 ++-- zone/embparser_api.cpp | 20 ++++ zone/expedition.cpp | 45 ++++---- zone/expedition.h | 5 +- zone/expedition_database.cpp | 8 +- zone/expedition_database.h | 2 +- zone/lua_expedition.cpp | 6 ++ zone/lua_expedition.h | 1 + zone/lua_general.cpp | 5 + zone/perl_expedition.cpp | 14 +++ 19 files changed, 182 insertions(+), 173 deletions(-) diff --git a/common/database_instances.cpp b/common/database_instances.cpp index 7bfb548ce..2cf3923fa 100644 --- a/common/database_instances.cpp +++ b/common/database_instances.cpp @@ -496,9 +496,6 @@ void Database::DeleteInstance(uint16 instance_id) query = fmt::format("DELETE FROM dynamic_zones WHERE instance_id={}", instance_id); QueryDatabase(query); - query = fmt::format("UPDATE expeditions SET instance_id = NULL WHERE instance_id={}", instance_id); - QueryDatabase(query); - BuryCorpsesInInstance(instance_id); } @@ -589,7 +586,6 @@ void Database::PurgeExpiredInstances() QueryDatabase(fmt::format("DELETE FROM spawn_condition_values WHERE instance_id IN ({})", imploded_instance_ids)); QueryDatabase(fmt::format("UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", imploded_instance_ids)); QueryDatabase(fmt::format("DELETE FROM dynamic_zones WHERE instance_id IN ({})", imploded_instance_ids)); - QueryDatabase(fmt::format("UPDATE expeditions SET instance_id = NULL WHERE instance_id IN ({})", imploded_instance_ids)); } void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration) diff --git a/utils/sql/git/required/wip_expeditions.sql b/utils/sql/git/required/wip_expeditions.sql index 90b3286c0..64f99eecd 100644 --- a/utils/sql/git/required/wip_expeditions.sql +++ b/utils/sql/git/required/wip_expeditions.sql @@ -1,7 +1,7 @@ CREATE TABLE `expeditions` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` VARCHAR(36) NOT NULL, - `instance_id` INT(10) NULL DEFAULT 0, + `dynamic_zone_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, `expedition_name` VARCHAR(128) NOT NULL, `leader_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, `min_players` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0, @@ -9,7 +9,7 @@ CREATE TABLE `expeditions` ( `add_replay_on_join` TINYINT(3) UNSIGNED NOT NULL DEFAULT 1, `is_locked` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), - UNIQUE INDEX `instance_id` (`instance_id`) + UNIQUE INDEX `dynamic_zone_id` (`dynamic_zone_id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB diff --git a/world/expedition.cpp b/world/expedition.cpp index 9a2dd58df..7b8b27ca0 100644 --- a/world/expedition.cpp +++ b/world/expedition.cpp @@ -26,12 +26,12 @@ extern ZSList zoneserver_list; -Expedition::Expedition( - uint32_t expedition_id, uint32_t instance_id, uint32_t dz_zone_id, - uint32_t start_time, uint32_t duration +Expedition::Expedition(uint32_t expedition_id, uint32_t dz_id, uint32_t dz_instance_id, + uint32_t dz_zone_id, uint32_t start_time, uint32_t duration ) : m_expedition_id(expedition_id), - m_dz_instance_id(instance_id), + m_dz_id(dz_id), + m_dz_instance_id(dz_instance_id), m_dz_zone_id(dz_zone_id), m_start_time(std::chrono::system_clock::from_time_t(start_time)), m_duration(duration) diff --git a/world/expedition.h b/world/expedition.h index c0c0da9a9..7cd9af996 100644 --- a/world/expedition.h +++ b/world/expedition.h @@ -30,8 +30,8 @@ class Expedition { public: Expedition() = default; - Expedition(uint32_t expedition_id, uint32_t instance_id, uint32_t dz_zone_id, - uint32_t expire_time, uint32_t duration); + Expedition(uint32_t expedition_id, uint32_t dz_id, uint32_t dz_instance_id, + uint32_t dz_zone_id, uint32_t expire_time, uint32_t duration); void AddMember(uint32_t character_id) { m_member_ids.emplace(character_id); } void RemoveMember(uint32_t character_id) { m_member_ids.erase(character_id); } @@ -43,6 +43,7 @@ public: bool IsEmpty() const { return m_member_ids.empty(); } bool IsExpired() const { return m_expire_time < std::chrono::system_clock::now(); } bool IsPendingDelete() const { return m_pending_delete; } + bool IsValid() const { return m_expedition_id != 0; } void SendZonesDurationUpdate(); void SendZonesExpeditionDeleted(); void SendZonesExpireWarning(uint32_t minutes_remaining); @@ -52,6 +53,7 @@ public: private: uint32_t m_expedition_id = 0; + uint32_t m_dz_id = 0; uint32_t m_dz_instance_id = 0; uint32_t m_dz_zone_id = 0; bool m_pending_delete = false; diff --git a/world/expedition_database.cpp b/world/expedition_database.cpp index 32fa4cecb..a9bea02e5 100644 --- a/world/expedition_database.cpp +++ b/world/expedition_database.cpp @@ -28,7 +28,8 @@ void ExpeditionDatabase::PurgeExpiredExpeditions() SELECT expeditions.id FROM expeditions - LEFT JOIN instance_list ON expeditions.instance_id = instance_list.id + LEFT JOIN dynamic_zones ON expeditions.dynamic_zone_id = dynamic_zones.id + LEFT JOIN instance_list ON dynamic_zones.instance_id = instance_list.id LEFT JOIN ( SELECT expedition_id, COUNT(*) member_count @@ -64,24 +65,34 @@ void ExpeditionDatabase::PurgeExpiredCharacterLockouts() database.QueryDatabase(query); } -std::vector ExpeditionDatabase::LoadExpeditions() +std::vector ExpeditionDatabase::LoadExpeditions(uint32_t select_expedition_id) { std::vector expeditions; std::string query = SQL( SELECT expeditions.id, - expeditions.instance_id, + expeditions.dynamic_zone_id, + instance_list.id, instance_list.zone, instance_list.start_time, instance_list.duration, expedition_members.character_id FROM expeditions - INNER JOIN instance_list ON expeditions.instance_id = instance_list.id + INNER JOIN dynamic_zones ON expeditions.dynamic_zone_id = dynamic_zones.id + INNER JOIN instance_list ON dynamic_zones.instance_id = instance_list.id INNER JOIN expedition_members ON expedition_members.expedition_id = expeditions.id - ORDER BY expeditions.id; ); + if (select_expedition_id != 0) + { + query.append(fmt::format(" WHERE expeditions.id = {};", select_expedition_id)); + } + else + { + query.append(" ORDER BY expeditions.id;"); + } + auto results = database.QueryDatabase(query); if (results.Success()) { @@ -95,16 +106,17 @@ std::vector ExpeditionDatabase::LoadExpeditions() { expeditions.emplace_back( static_cast(strtoul(row[0], nullptr, 10)), // expedition_id - static_cast(strtoul(row[1], nullptr, 10)), // dz_instance_id - static_cast(strtoul(row[2], nullptr, 10)), // dz_zone_id - static_cast(strtoul(row[3], nullptr, 10)), // start_time - static_cast(strtoul(row[4], nullptr, 10)) // duration + static_cast(strtoul(row[1], nullptr, 10)), // dz_id + static_cast(strtoul(row[2], nullptr, 10)), // dz_instance_id + static_cast(strtoul(row[3], nullptr, 10)), // dz_zone_id + static_cast(strtoul(row[4], nullptr, 10)), // start_time + static_cast(strtoul(row[5], nullptr, 10)) // duration ); } last_expedition_id = expedition_id; - uint32_t member_id = static_cast(strtoul(row[5], nullptr, 10)); + uint32_t member_id = static_cast(strtoul(row[6], nullptr, 10)); expeditions.back().AddMember(member_id); } } @@ -118,41 +130,10 @@ Expedition ExpeditionDatabase::LoadExpedition(uint32_t expedition_id) Expedition expedition; - std::string query = fmt::format(SQL( - SELECT - expeditions.id, - expeditions.instance_id, - instance_list.zone, - instance_list.start_time, - instance_list.duration, - expedition_members.character_id - FROM expeditions - INNER JOIN instance_list ON expeditions.instance_id = instance_list.id - INNER JOIN expedition_members ON expedition_members.expedition_id = expeditions.id - WHERE expeditions.id = {}; - ), expedition_id); - - auto results = database.QueryDatabase(query); - if (results.Success()) + auto expeditions = LoadExpeditions(expedition_id); + if (!expeditions.empty()) { - bool created = false; - for (auto row = results.begin(); row != results.end(); ++row) - { - if (!created) - { - expedition = Expedition{ - static_cast(strtoul(row[0], nullptr, 10)), // expedition_id - static_cast(strtoul(row[1], nullptr, 10)), // dz_instance_id - static_cast(strtoul(row[2], nullptr, 10)), // dz_zone_id - static_cast(strtoul(row[3], nullptr, 10)), // start_time - static_cast(strtoul(row[4], nullptr, 10)) // duration - }; - created = true; - } - - auto member_id = static_cast(strtoul(row[5], nullptr, 10)); - expedition.AddMember(member_id); - } + expedition = expeditions.front(); } return expedition; diff --git a/world/expedition_database.h b/world/expedition_database.h index ea33e823b..ff01f0107 100644 --- a/world/expedition_database.h +++ b/world/expedition_database.h @@ -29,7 +29,7 @@ class Expedition; namespace ExpeditionDatabase { void DeleteExpeditions(const std::vector& expedition_ids); - std::vector LoadExpeditions(); + std::vector LoadExpeditions(uint32_t select_expedition_id = 0); Expedition LoadExpedition(uint32_t expedition_id); void PurgeExpiredExpeditions(); void PurgeExpiredCharacterLockouts(); diff --git a/world/expedition_state.cpp b/world/expedition_state.cpp index d97c4f72e..d6a38e912 100644 --- a/world/expedition_state.cpp +++ b/world/expedition_state.cpp @@ -49,7 +49,7 @@ void ExpeditionState::AddExpedition(uint32_t expedition_id) auto expedition = ExpeditionDatabase::LoadExpedition(expedition_id); - if (expedition.GetID() == expedition_id) + if (expedition.IsValid()) { auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(), [&](const Expedition& expedition) { return expedition.GetID() == expedition_id; diff --git a/zone/command.cpp b/zone/command.cpp index e806474ae..fd20a1ac1 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -6844,8 +6844,9 @@ void command_dz(Client* c, const Seperator* sep) auto seconds = expedition.second->GetDynamicZone().GetSecondsRemaining(); c->Message(Chat::White, fmt::format( - "Expedition id: [{}] name: [{}] leader: [{}] zone: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]", + "expedition id: [{}] dz id: [{}] name: [{}] leader: [{}] zone: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]", expedition.second->GetID(), + expedition.second->GetDynamicZoneID(), expedition.second->GetName(), expedition.second->GetLeaderName(), ZoneName(expedition.second->GetDynamicZone().GetZoneID()), @@ -6900,6 +6901,7 @@ void command_dz(Client* c, const Seperator* sep) { std::string query = SQL( SELECT + dynamic_zones.id, dynamic_zones.type, instance_list.id, instance_list.zone, @@ -6919,8 +6921,8 @@ void command_dz(Client* c, const Seperator* sep) c->Message(Chat::White, fmt::format("Total Dynamic Zones: [{}]", results.RowCount()).c_str()); for (auto row = results.begin(); row != results.end(); ++row) { - auto start_time = strtoul(row[4], nullptr, 10); - auto duration = strtoul(row[5], nullptr, 10); + auto start_time = strtoul(row[5], nullptr, 10); + auto duration = strtoul(row[6], nullptr, 10); auto expire_time = std::chrono::system_clock::from_time_t(start_time + duration); auto now = std::chrono::system_clock::now(); @@ -6931,12 +6933,13 @@ void command_dz(Client* c, const Seperator* sep) if (!is_expired || strcasecmp(sep->arg[2], "all") == 0) { c->Message(Chat::White, fmt::format( - "type: [{}] zone: [{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]", - strtoul(row[0], nullptr, 10), - strtoul(row[2], nullptr, 10), - strtoul(row[1], nullptr, 10), - strtoul(row[3], nullptr, 10), - strtoul(row[6], nullptr, 10), + "dz id: [{}] type: [{}] zone: [{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]", + strtoul(row[0], nullptr, 10), // dynamic_zone_id + strtoul(row[1], nullptr, 10), // dynamic_zone_type + strtoul(row[3], nullptr, 10), // instance_zone_id + strtoul(row[2], nullptr, 10), // instance_id + strtoul(row[4], nullptr, 10), // instance_zone_version + strtoul(row[7], nullptr, 10), // instance member_count seconds / 3600, // hours (seconds / 60) % 60, // minutes seconds % 60 // seconds diff --git a/zone/dynamiczone.cpp b/zone/dynamiczone.cpp index ea22e4b4f..5e86ddc00 100644 --- a/zone/dynamiczone.cpp +++ b/zone/dynamiczone.cpp @@ -51,36 +51,26 @@ DynamicZone::DynamicZone( } } -DynamicZone DynamicZone::LoadDzFromDatabase(uint32_t instance_id) -{ - DynamicZone dynamic_zone; - if (instance_id != 0) - { - dynamic_zone.LoadFromDatabase(instance_id); - } - return dynamic_zone; -} - std::unordered_map DynamicZone::LoadMultipleDzFromDatabase( - const std::vector& instance_ids) + const std::vector& dynamic_zone_ids) { - LogDynamicZonesDetail("Loading dynamic zone data for [{}] instances", instance_ids.size()); + LogDynamicZonesDetail("Loading dynamic zone data for [{}] instances", dynamic_zone_ids.size()); - std::string in_instance_ids_query; - for (const auto& instance_id : instance_ids) + std::string in_dynamic_zone_ids_query; + for (const auto& dynamic_zone_id : dynamic_zone_ids) { - fmt::format_to(std::back_inserter(in_instance_ids_query), "{},", instance_id); + fmt::format_to(std::back_inserter(in_dynamic_zone_ids_query), "{},", dynamic_zone_id); } std::unordered_map dynamic_zones; - if (!in_instance_ids_query.empty()) + if (!in_dynamic_zone_ids_query.empty()) { - in_instance_ids_query.pop_back(); // trailing comma + in_dynamic_zone_ids_query.pop_back(); // trailing comma std::string query = fmt::format(SQL( - {} WHERE dynamic_zones.instance_id IN ({}); - ), DynamicZoneSelectQuery(), in_instance_ids_query); + {} WHERE dynamic_zones.id IN ({}); + ), DynamicZoneSelectQuery(), in_dynamic_zone_ids_query); auto results = database.QueryDatabase(query); if (results.Success()) @@ -89,7 +79,7 @@ std::unordered_map DynamicZone::LoadMultipleDzFromDatabas { DynamicZone dz; dz.LoadDatabaseResult(row); - dynamic_zones.emplace(dz.GetInstanceID(), dz); + dynamic_zones.emplace(dz.GetID(), dz); } } } @@ -97,6 +87,23 @@ std::unordered_map DynamicZone::LoadMultipleDzFromDatabas return dynamic_zones; } +uint32_t DynamicZone::Create() +{ + if (m_id != 0) + { + return m_id; + } + + if (GetInstanceID() == 0) + { + CreateInstance(); + } + + m_id = SaveToDatabase(); + + return m_id; +} + uint32_t DynamicZone::CreateInstance() { if (m_instance_id) @@ -152,6 +159,7 @@ std::string DynamicZone::DynamicZoneSelectQuery() instance_list.start_time, instance_list.duration, instance_list.never_expires, + dynamic_zones.id, dynamic_zones.type, dynamic_zones.compass_zone_id, dynamic_zones.compass_x, @@ -181,42 +189,22 @@ void DynamicZone::LoadDatabaseResult(MySQLRequestRow& row) m_duration = std::chrono::seconds(strtoul(row[4], nullptr, 10)); m_expire_time = m_start_time + m_duration; m_never_expires = (strtoul(row[5], nullptr, 10) != 0); - m_type = static_cast(strtoul(row[6], nullptr, 10)); - m_compass.zone_id = strtoul(row[7], nullptr, 10); - m_compass.x = strtof(row[8], nullptr); - m_compass.y = strtof(row[9], nullptr); - m_compass.z = strtof(row[10], nullptr); - m_safereturn.zone_id = strtoul(row[11], nullptr, 10); - m_safereturn.x = strtof(row[12], nullptr); - m_safereturn.y = strtof(row[13], nullptr); - m_safereturn.z = strtof(row[14], nullptr); - m_safereturn.heading = strtof(row[15], nullptr); - m_zonein.x = strtof(row[16], nullptr); - m_zonein.y = strtof(row[17], nullptr); - m_zonein.z = strtof(row[18], nullptr); - m_zonein.heading = strtof(row[19], nullptr); - m_has_zonein = (strtoul(row[20], nullptr, 10) != 0); -} - -void DynamicZone::LoadFromDatabase(uint32_t instance_id) -{ - if (instance_id == 0) - { - return; - } - - LogDynamicZonesDetail("Loading dz instance [{}] from database", instance_id); - - std::string query = fmt::format(SQL( - {} WHERE dynamic_zones.instance_id = {}; - ), DynamicZoneSelectQuery(), instance_id); - - auto results = database.QueryDatabase(query); - if (results.Success() && results.RowCount() > 0) - { - auto row = results.begin(); - LoadDatabaseResult(row); - } + m_id = strtoul(row[6], nullptr, 10); + m_type = static_cast(strtoul(row[7], nullptr, 10)); + m_compass.zone_id = strtoul(row[8], nullptr, 10); + m_compass.x = strtof(row[9], nullptr); + m_compass.y = strtof(row[10], nullptr); + m_compass.z = strtof(row[11], nullptr); + m_safereturn.zone_id = strtoul(row[12], nullptr, 10); + m_safereturn.x = strtof(row[13], nullptr); + m_safereturn.y = strtof(row[14], nullptr); + m_safereturn.z = strtof(row[15], nullptr); + m_safereturn.heading = strtof(row[16], nullptr); + m_zonein.x = strtof(row[17], nullptr); + m_zonein.y = strtof(row[18], nullptr); + m_zonein.z = strtof(row[19], nullptr); + m_zonein.heading = strtof(row[20], nullptr); + m_has_zonein = (strtoul(row[21], nullptr, 10) != 0); } uint32_t DynamicZone::SaveToDatabase() @@ -363,21 +351,6 @@ void DynamicZone::SaveZoneInLocationToDatabase() } } - -void DynamicZone::DeleteFromDatabase() -{ - LogDynamicZonesDetail("Deleting dz instance [{}] from database", m_instance_id); - - if (m_instance_id != 0) - { - std::string query = fmt::format(SQL( - DELETE FROM dynamic_zones WHERE instance_id = {}; - ), m_instance_id); - - database.QueryDatabase(query); - } -} - void DynamicZone::AddCharacter(uint32_t character_id) { database.AddClientToInstance(m_instance_id, character_id); diff --git a/zone/dynamiczone.h b/zone/dynamiczone.h index 693107840..d519539e0 100644 --- a/zone/dynamiczone.h +++ b/zone/dynamiczone.h @@ -59,37 +59,36 @@ public: DynamicZone() = default; DynamicZone(uint32_t zone_id, uint32_t version, uint32_t duration, DynamicZoneType type); DynamicZone(std::string zone_shortname, uint32_t version, uint32_t duration, DynamicZoneType type); - DynamicZone(uint32_t instance_id) : m_instance_id(instance_id) {} + DynamicZone(uint32_t dz_id) : m_id(dz_id) {} DynamicZone(DynamicZoneType type) : m_type(type) {} - static DynamicZone LoadDzFromDatabase(uint32_t instance_id); static std::unordered_map LoadMultipleDzFromDatabase( - const std::vector& instance_ids); + const std::vector& dynamic_zone_ids); static void HandleWorldMessage(ServerPacket* pack); uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); } - uint16_t GetInstanceID() const { return static_cast(m_instance_id); }; + uint32_t GetID() const { return m_id; } + uint16_t GetInstanceID() const { return static_cast(m_instance_id); } uint32_t GetSecondsRemaining() const; - uint16_t GetZoneID() const { return static_cast(m_zone_id); }; + uint16_t GetZoneID() const { return static_cast(m_zone_id); } uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); } - uint32_t GetZoneVersion() const { return m_version; }; + uint32_t GetZoneVersion() const { return m_version; } DynamicZoneType GetType() const { return m_type; } DynamicZoneLocation GetCompassLocation() const { return m_compass; } DynamicZoneLocation GetSafeReturnLocation() const { return m_safereturn; } DynamicZoneLocation GetZoneInLocation() const { return m_zonein; } void AddCharacter(uint32_t character_id); + uint32_t Create(); uint32_t CreateInstance(); bool HasZoneInLocation() const { return m_has_zonein; } bool IsCurrentZoneDzInstance() const; bool IsInstanceID(uint32_t instance_id) const; bool IsValid() const { return m_instance_id != 0; } bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const; - void LoadFromDatabase(uint32_t instance_id); void RemoveAllCharacters(bool enable_removal_timers = true); void RemoveCharacter(uint32_t character_id); void SaveInstanceMembersToDatabase(const std::vector& character_ids); - uint32_t SaveToDatabase(); void SendInstanceCharacterChange(uint32_t character_id, bool removed); void SetCompass(const DynamicZoneLocation& location, bool update_db = false); void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false); @@ -99,11 +98,12 @@ public: private: static std::string DynamicZoneSelectQuery(); void LoadDatabaseResult(MySQLRequestRow& row); - void DeleteFromDatabase(); void SaveCompassToDatabase(); void SaveSafeReturnToDatabase(); void SaveZoneInLocationToDatabase(); + uint32_t SaveToDatabase(); + uint32_t m_id = 0; uint32_t m_zone_id = 0; uint32_t m_instance_id = 0; uint32_t m_version = 0; diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 71affe083..51414aef7 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -6101,6 +6101,25 @@ XS(XS__get_expedition_by_char_id) { XSRETURN(1); } +XS(XS__get_expedition_by_dz_id); +XS(XS__get_expedition_by_dz_id) { + dXSARGS; + if (items != 1) { + Perl_croak(aTHX_ "Usage: quest::get_expedition_by_dz_id(uint32 dynamic_zone_id)"); + } + + uint32 dz_id = (int)SvUV(ST(0)); + + Expedition* RETVAL = Expedition::FindCachedExpeditionByDynamicZoneID(dz_id); + + ST(0) = sv_newmortal(); + if (RETVAL) { + sv_setref_pv(ST(0), "Expedition", (void*)RETVAL); + } + + XSRETURN(1); +} + XS(XS__get_expedition_by_zone_instance); XS(XS__get_expedition_by_zone_instance) { dXSARGS; @@ -6507,6 +6526,7 @@ EXTERN_C XS(boot_quest) { newXS(strcpy(buf, "getcurrencyid"), XS__getcurrencyid, file); newXS(strcpy(buf, "get_expedition"), XS__get_expedition, file); newXS(strcpy(buf, "get_expedition_by_char_id"), XS__get_expedition_by_char_id, file); + newXS(strcpy(buf, "get_expedition_by_dz_id"), XS__get_expedition_by_dz_id, file); newXS(strcpy(buf, "get_expedition_by_zone_instance"), XS__get_expedition_by_zone_instance, file); newXS(strcpy(buf, "get_expedition_lockout_by_char_id"), XS__get_expedition_lockout_by_char_id, file); newXS(strcpy(buf, "get_expedition_lockouts_by_char_id"), XS__get_expedition_lockouts_by_char_id, file); diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 4d8966c76..7f5e3d92c 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -78,12 +78,8 @@ Expedition* Expedition::TryCreate( return nullptr; } - if (dynamiczone.GetInstanceID() == 0) - { - dynamiczone.CreateInstance(); - } - - if (dynamiczone.GetInstanceID() == 0) + auto dynamic_zone_id = dynamiczone.Create(); + if (dynamic_zone_id == 0) { // live uses this message when trying to enter an instance that isn't ready // we can use it as the client error message if instance creation fails @@ -97,7 +93,7 @@ Expedition* Expedition::TryCreate( // unique expedition ids are created from database via auto-increment column auto expedition_id = ExpeditionDatabase::InsertExpedition( expedition_uuid, - dynamiczone.GetInstanceID(), + dynamiczone.GetID(), request.GetExpeditionName(), request.GetLeaderID(), request.GetMinPlayers(), @@ -106,8 +102,6 @@ Expedition* Expedition::TryCreate( if (expedition_id) { - dynamiczone.SaveToDatabase(); - auto expedition = std::unique_ptr(new Expedition( expedition_id, expedition_uuid, @@ -158,7 +152,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) } std::vector expedition_ids; - std::vector instance_ids; + std::vector dynamic_zone_ids;; std::vector> expedition_character_ids; using col = LoadExpeditionColumns::eLoadExpeditionColumns; @@ -174,16 +168,14 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) expedition_ids.emplace_back(expedition_id); uint32_t leader_id = strtoul(row[col::leader_id], nullptr, 10); - uint32_t instance_id = row[col::instance_id] ? strtoul(row[col::instance_id], nullptr, 10) : 0; - if (instance_id) // can be null from fk constraint - { - instance_ids.emplace_back(instance_id); - } + uint32_t dynamic_zone_id = strtoul(row[col::dz_id], nullptr, 10); + + dynamic_zone_ids.emplace_back(dynamic_zone_id); std::unique_ptr expedition = std::unique_ptr(new Expedition( expedition_id, row[col::uuid], // expedition uuid - DynamicZone{ instance_id }, + DynamicZone{ dynamic_zone_id }, row[col::expedition_name], // expedition name ExpeditionMember{ leader_id, row[col::leader_name] }, // expedition leader id, name strtoul(row[col::min_players], nullptr, 10), // min_players @@ -216,7 +208,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) Expedition::SendWorldGetOnlineMembers(expedition_character_ids); // bulk load dynamic zone data and expedition lockouts for cached expeditions - auto dynamic_zones = DynamicZone::LoadMultipleDzFromDatabase(instance_ids); + auto dynamic_zones = DynamicZone::LoadMultipleDzFromDatabase(dynamic_zone_ids); auto expedition_lockouts = ExpeditionDatabase::LoadMultipleExpeditionLockouts(expedition_ids); for (const auto& expedition_id : expedition_ids) @@ -224,7 +216,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) auto expedition = Expedition::FindCachedExpeditionByID(expedition_id); if (expedition) { - auto dz_iter = dynamic_zones.find(expedition->GetInstanceID()); + auto dz_iter = dynamic_zones.find(expedition->GetDynamicZoneID()); if (dz_iter != dynamic_zones.end()) { expedition->m_dynamiczone = dz_iter->second; @@ -236,7 +228,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) expedition->m_lockouts = lockout_iter->second; } - // send member updates now that all data is loaded for the cached expedition(s) + // send member updates now that all data is loaded for the cached expedition expedition->SendUpdatesToZoneMembers(); } } @@ -340,6 +332,21 @@ Expedition* Expedition::FindCachedExpeditionByCharacterName(const std::string& c return nullptr; } +Expedition* Expedition::FindCachedExpeditionByDynamicZoneID(uint32_t dz_id) +{ + if (zone && dz_id != 0) + { + for (const auto& cached_expedition : zone->expedition_cache) + { + if (cached_expedition.second->GetDynamicZone().GetID() == dz_id) + { + return cached_expedition.second.get(); + } + } + } + return nullptr; +} + Expedition* Expedition::FindCachedExpeditionByID(uint32_t expedition_id) { if (zone && expedition_id) diff --git a/zone/expedition.h b/zone/expedition.h index 52595da40..59298093b 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -74,8 +74,7 @@ class Expedition { public: Expedition() = delete; - Expedition( - uint32_t id, const std::string& uuid, const DynamicZone& dz, const std::string& expedition_name, + Expedition(uint32_t id, const std::string& uuid, const DynamicZone& dz, const std::string& expedition_name, const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players); static Expedition* TryCreate(Client* requester, DynamicZone& dynamiczone, ExpeditionRequest& request); @@ -84,6 +83,7 @@ public: static bool CacheAllFromDatabase(); static Expedition* FindCachedExpeditionByCharacterID(uint32_t character_id); static Expedition* FindCachedExpeditionByCharacterName(const std::string& char_name); + static Expedition* FindCachedExpeditionByDynamicZoneID(uint32_t dz_id); static Expedition* FindCachedExpeditionByID(uint32_t expedition_id); static Expedition* FindCachedExpeditionByZoneInstance(uint32_t zone_id, uint32_t instance_id); static std::vector GetExpeditionLockoutsByCharacterID(uint32_t character_id); @@ -102,6 +102,7 @@ public: const std::string& expedition_name = {}, const std::string& event_name = {}); static void AddLockoutClients(const ExpeditionLockoutTimer& lockout, uint32_t exclude_id = 0); + uint32_t GetDynamicZoneID() const { return m_dynamiczone.GetID(); } uint32_t GetID() const { return m_id; } uint16_t GetInstanceID() const { return m_dynamiczone.GetInstanceID(); } uint32_t GetLeaderID() const { return m_leader.char_id; } diff --git a/zone/expedition_database.cpp b/zone/expedition_database.cpp index 41dcc8cad..1977b36bd 100644 --- a/zone/expedition_database.cpp +++ b/zone/expedition_database.cpp @@ -27,7 +27,7 @@ #include uint32_t ExpeditionDatabase::InsertExpedition( - const std::string& uuid, uint32_t instance_id, const std::string& expedition_name, + const std::string& uuid, uint32_t dz_id, const std::string& expedition_name, uint32_t leader_id, uint32_t min_players, uint32_t max_players) { LogExpeditionsDetail( @@ -36,10 +36,10 @@ uint32_t ExpeditionDatabase::InsertExpedition( std::string query = fmt::format(SQL( INSERT INTO expeditions - (uuid, instance_id, expedition_name, leader_id, min_players, max_players) + (uuid, dynamic_zone_id, expedition_name, leader_id, min_players, max_players) VALUES ('{}', {}, '{}', {}, {}, {}); - ), uuid, instance_id, EscapeString(expedition_name), leader_id, min_players, max_players); + ), uuid, dz_id, EscapeString(expedition_name), leader_id, min_players, max_players); auto results = database.QueryDatabase(query); if (!results.Success()) @@ -57,7 +57,7 @@ std::string ExpeditionDatabase::LoadExpeditionsSelectQuery() SELECT expeditions.id, expeditions.uuid, - expeditions.instance_id, + expeditions.dynamic_zone_id, expeditions.expedition_name, expeditions.leader_id, expeditions.min_players, diff --git a/zone/expedition_database.h b/zone/expedition_database.h index 4335f29b4..519a331f4 100644 --- a/zone/expedition_database.h +++ b/zone/expedition_database.h @@ -84,7 +84,7 @@ namespace LoadExpeditionColumns { id = 0, uuid, - instance_id, + dz_id, expedition_name, leader_id, min_players, diff --git a/zone/lua_expedition.cpp b/zone/lua_expedition.cpp index d5c1d4490..28f783dd1 100644 --- a/zone/lua_expedition.cpp +++ b/zone/lua_expedition.cpp @@ -57,6 +57,11 @@ void Lua_Expedition::AddReplayLockoutDuration(int seconds, bool members_only) { self->AddReplayLockoutDuration(seconds, members_only); } +uint32_t Lua_Expedition::GetDynamicZoneID() { + Lua_Safe_Call_Int(); + return self->GetDynamicZoneID(); +} + uint32_t Lua_Expedition::GetID() { Lua_Safe_Call_Int(); return self->GetID(); @@ -248,6 +253,7 @@ luabind::scope lua_register_expedition() { .def("AddReplayLockout", (void(Lua_Expedition::*)(uint32_t))&Lua_Expedition::AddReplayLockout) .def("AddReplayLockoutDuration", (void(Lua_Expedition::*)(int))&Lua_Expedition::AddReplayLockoutDuration) .def("AddReplayLockoutDuration", (void(Lua_Expedition::*)(int, bool))&Lua_Expedition::AddReplayLockoutDuration) + .def("GetDynamicZoneID", &Lua_Expedition::GetDynamicZoneID) .def("GetID", (uint32_t(Lua_Expedition::*)(void))&Lua_Expedition::GetID) .def("GetInstanceID", (int(Lua_Expedition::*)(void))&Lua_Expedition::GetInstanceID) .def("GetLeaderName", (std::string(Lua_Expedition::*)(void))&Lua_Expedition::GetLeaderName) diff --git a/zone/lua_expedition.h b/zone/lua_expedition.h index d904d1680..6409d574a 100644 --- a/zone/lua_expedition.h +++ b/zone/lua_expedition.h @@ -59,6 +59,7 @@ public: void AddReplayLockout(uint32_t seconds); void AddReplayLockoutDuration(int seconds); void AddReplayLockoutDuration(int seconds, bool members_only); + uint32_t GetDynamicZoneID(); uint32_t GetID(); int GetInstanceID(); std::string GetLeaderName(); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index f12d3a3d6..34cc30b29 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -2192,6 +2192,10 @@ Lua_Expedition lua_get_expedition_by_char_id(uint32 char_id) { return Expedition::FindCachedExpeditionByCharacterID(char_id); } +Lua_Expedition lua_get_expedition_by_dz_id(uint32 dz_id) { + return Expedition::FindCachedExpeditionByDynamicZoneID(dz_id); +} + Lua_Expedition lua_get_expedition_by_zone_instance(uint32 zone_id, uint32 instance_id) { return Expedition::FindCachedExpeditionByZoneInstance(zone_id, instance_id); } @@ -2889,6 +2893,7 @@ luabind::scope lua_register_general() { luabind::def("get_expedition", &lua_get_expedition), luabind::def("get_expedition_by_char_id", &lua_get_expedition_by_char_id), + luabind::def("get_expedition_by_dz_id", &lua_get_expedition_by_dz_id), luabind::def("get_expedition_by_zone_instance", &lua_get_expedition_by_zone_instance), luabind::def("get_expedition_lockout_by_char_id", &lua_get_expedition_lockout_by_char_id), luabind::def("get_expedition_lockouts_by_char_id", (luabind::object(*)(lua_State*, uint32))&lua_get_expedition_lockouts_by_char_id), diff --git a/zone/perl_expedition.cpp b/zone/perl_expedition.cpp index e7e0f3bb2..a3d7fc217 100644 --- a/zone/perl_expedition.cpp +++ b/zone/perl_expedition.cpp @@ -132,6 +132,19 @@ XS(XS_Expedition_AddReplayLockoutDuration) { XSRETURN_EMPTY; } +XS(XS_Expedition_GetDynamicZoneID); +XS(XS_Expedition_GetDynamicZoneID) { + dXSARGS; + if (items != 1) { + Perl_croak(aTHX_ "Usage: Expedition::GetDynamicZoneID(THIS)"); + } + + Expedition* THIS = nullptr; + VALIDATE_THIS_IS_EXPEDITION; + + XSRETURN_UV(THIS->GetDynamicZoneID()); +} + XS(XS_Expedition_GetID); XS(XS_Expedition_GetID) { dXSARGS; @@ -623,6 +636,7 @@ XS(boot_Expedition) { newXSproto(strcpy(buf, "AddLockoutDuration"), XS_Expedition_AddLockoutDuration, file, "$$$;$"); newXSproto(strcpy(buf, "AddReplayLockout"), XS_Expedition_AddReplayLockout, file, "$$"); newXSproto(strcpy(buf, "AddReplayLockoutDuration"), XS_Expedition_AddReplayLockoutDuration, file, "$$;$"); + newXSproto(strcpy(buf, "GetDynamicZoneID"), XS_Expedition_GetDynamicZoneID, file, "$"); newXSproto(strcpy(buf, "GetID"), XS_Expedition_GetID, file, "$"); newXSproto(strcpy(buf, "GetInstanceID"), XS_Expedition_GetInstanceID, file, "$"); newXSproto(strcpy(buf, "GetLeaderName"), XS_Expedition_GetLeaderName, file, "$");