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, "$");