From d9e23a0303252aa15676cda4c86b880da17aa6fc Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Sun, 28 Mar 2021 19:14:36 -0400 Subject: [PATCH] [Expeditions] Decouple dz updates from expeditions (#1303) Use internal dz messages to process duration and location changes Add world DynamicZone class (later this will inherit from a base) Add FindDynamicZoneByID to get dz from zone and world system caches --- common/eq_constants.h | 10 ++ .../repositories/instance_list_repository.h | 9 ++ common/servertalk.h | 26 ++-- world/CMakeLists.txt | 2 + world/dynamic_zone.cpp | 103 ++++++++++++++++ world/dynamic_zone.h | 42 +++++++ world/expedition.cpp | 56 +-------- world/expedition.h | 18 +-- world/expedition_database.cpp | 31 +++-- world/expedition_database.h | 1 - world/expedition_message.cpp | 6 - world/expedition_state.cpp | 23 ++-- world/expedition_state.h | 2 +- world/zoneserver.cpp | 16 +-- zone/dynamic_zone.cpp | 108 ++++++++++++++-- zone/dynamic_zone.h | 20 +-- zone/expedition.cpp | 116 +----------------- zone/expedition.h | 11 +- zone/lua_expedition.cpp | 14 +-- zone/perl_expedition.cpp | 14 +-- zone/worldserver.cpp | 8 +- 21 files changed, 350 insertions(+), 286 deletions(-) create mode 100644 world/dynamic_zone.cpp create mode 100644 world/dynamic_zone.h diff --git a/common/eq_constants.h b/common/eq_constants.h index 1a0c517bd..cb042043f 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -464,4 +464,14 @@ namespace ZoneBlockedSpellTypes { const uint8 Region = 2; }; +enum class DynamicZoneType +{ + None = 0, + Expedition, + Tutorial, + Task, + Mission, // Shared Task + Quest +}; + #endif /*COMMON_EQ_CONSTANTS_H*/ diff --git a/common/repositories/instance_list_repository.h b/common/repositories/instance_list_repository.h index 312211295..6af82e302 100644 --- a/common/repositories/instance_list_repository.h +++ b/common/repositories/instance_list_repository.h @@ -65,6 +65,15 @@ public: // Custom extended repository methods here + static int UpdateDuration(Database& db, int instance_id, uint32_t new_duration) + { + auto results = db.QueryDatabase(fmt::format( + "UPDATE {} SET duration = {} WHERE {} = {};", + TableName(), new_duration, PrimaryKey(), instance_id + )); + + return (results.Success() ? results.RowsAffected() : 0); + } }; #endif //EQEMU_INSTANCE_LIST_REPOSITORY_H diff --git a/common/servertalk.h b/common/servertalk.h index 40be635ad..e86dd2c86 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -151,23 +151,23 @@ #define ServerOP_ExpeditionGetOnlineMembers 0x0407 #define ServerOP_ExpeditionDzAddPlayer 0x0408 #define ServerOP_ExpeditionDzMakeLeader 0x0409 -#define ServerOP_ExpeditionDzCompass 0x040a -#define ServerOP_ExpeditionDzSafeReturn 0x040b -#define ServerOP_ExpeditionDzZoneIn 0x040c #define ServerOP_ExpeditionCharacterLockout 0x040d #define ServerOP_ExpeditionSaveInvite 0x040e #define ServerOP_ExpeditionRequestInvite 0x040f #define ServerOP_ExpeditionReplayOnJoin 0x0410 #define ServerOP_ExpeditionLockState 0x0411 #define ServerOP_ExpeditionMembersRemoved 0x0412 -#define ServerOP_ExpeditionDzDuration 0x0413 #define ServerOP_ExpeditionLockoutDuration 0x0414 -#define ServerOP_ExpeditionSecondsRemaining 0x0415 #define ServerOP_ExpeditionExpireWarning 0x0416 #define ServerOP_ExpeditionChooseNewLeader 0x0417 #define ServerOP_DzCharacterChange 0x0450 #define ServerOP_DzRemoveAllCharacters 0x0451 +#define ServerOP_DzSetSecondsRemaining 0x0452 +#define ServerOP_DzDurationUpdate 0x0453 +#define ServerOP_DzSetCompass 0x0454 +#define ServerOP_DzSetSafeReturn 0x0455 +#define ServerOP_DzSetZoneIn 0x0456 #define ServerOP_LSInfo 0x1000 #define ServerOP_LSStatus 0x1001 @@ -2090,11 +2090,6 @@ struct ServerExpeditionCharacterID_Struct { uint32_t character_id; }; -struct ServerExpeditionUpdateDuration_Struct { - uint32_t expedition_id; - uint32_t new_duration_seconds; -}; - struct ServerExpeditionExpireWarning_Struct { uint32_t expedition_id; uint32_t minutes_remaining; @@ -2117,12 +2112,10 @@ struct ServerDzCommandMakeLeader_Struct { }; struct ServerDzLocation_Struct { - uint32 owner_id; // system associated with the dz (expedition, shared task, etc) - uint16 dz_zone_id; - uint16 dz_instance_id; + uint32 dz_id; uint32 sender_zone_id; uint16 sender_instance_id; - uint32 zone_id; // compass or safereturn zone id + uint32 zone_id; float y; float x; float z; @@ -2136,6 +2129,11 @@ struct ServerDzCharacter_Struct { uint32 character_id; }; +struct ServerDzSetDuration_Struct { + uint32 dz_id; + uint32 seconds; +}; + #pragma pack() #endif diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index 50210f2f3..183f4a27d 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -7,6 +7,7 @@ SET(world_sources cliententry.cpp clientlist.cpp console.cpp + dynamic_zone.cpp eql_config.cpp eqemu_api_world_data_service.cpp expedition.cpp @@ -41,6 +42,7 @@ SET(world_headers cliententry.h clientlist.h console.h + dynamic_zone.h eql_config.h eqemu_api_world_data_service.h expedition.h diff --git a/world/dynamic_zone.cpp b/world/dynamic_zone.cpp new file mode 100644 index 000000000..47e70d00a --- /dev/null +++ b/world/dynamic_zone.cpp @@ -0,0 +1,103 @@ +#include "dynamic_zone.h" +#include "expedition.h" +#include "expedition_state.h" +#include "worlddb.h" +#include "zonelist.h" +#include "zoneserver.h" +#include "../common/eqemu_logsys.h" +#include "../common/repositories/instance_list_repository.h" + +extern ZSList zoneserver_list; + +DynamicZone::DynamicZone( + uint32_t id, uint32_t zone_id, uint32_t instance_id, uint32_t zone_version, + uint32_t start_time, uint32_t duration, DynamicZoneType type +) : + m_id(id), + m_instance_id(instance_id), + m_zone_id(zone_id), + m_zone_version(zone_version), + m_start_time(std::chrono::system_clock::from_time_t(start_time)), + m_duration(duration), + m_type(type), + m_expire_time(m_start_time + m_duration) +{ +} + +DynamicZone* DynamicZone::FindDynamicZoneByID(uint32_t dz_id) +{ + auto expedition = expedition_state.GetExpeditionByDynamicZoneID(dz_id); + if (expedition) + { + return &expedition->GetDynamicZone(); + } + // todo: other system caches + return nullptr; +} + +void DynamicZone::SetSecondsRemaining(uint32_t seconds_remaining) +{ + auto now = std::chrono::system_clock::now(); + auto new_remaining = std::chrono::seconds(seconds_remaining); + + auto current_remaining = m_expire_time - now; + if (current_remaining > new_remaining) // reduce only + { + LogDynamicZonesDetail("Updating dynamic zone [{}] instance [{}] seconds remaining to [{}]s", + GetID(), GetInstanceID(), seconds_remaining); + + // preserve original start time and adjust duration instead + m_expire_time = now + new_remaining; + m_duration = std::chrono::duration_cast(m_expire_time - m_start_time); + + InstanceListRepository::UpdateDuration(database, + GetInstanceID(), static_cast(m_duration.count())); + + SendZonesDurationUpdate(); // update zone caches and actual instance's timer + } +} + +void DynamicZone::SendZonesDurationUpdate() +{ + constexpr uint32_t packsize = sizeof(ServerDzSetDuration_Struct); + auto pack = std::make_unique(ServerOP_DzDurationUpdate, packsize); + auto packbuf = reinterpret_cast(pack->pBuffer); + packbuf->dz_id = GetID(); + packbuf->seconds = static_cast(m_duration.count()); + zoneserver_list.SendPacket(pack.get()); +} + +void DynamicZone::HandleZoneMessage(ServerPacket* pack) +{ + switch (pack->opcode) + { + case ServerOP_DzSetCompass: + case ServerOP_DzSetSafeReturn: + case ServerOP_DzSetZoneIn: + { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_DzCharacterChange: + case ServerOP_DzRemoveAllCharacters: + { + auto buf = reinterpret_cast(pack->pBuffer); + ZoneServer* instance_zs = zoneserver_list.FindByInstanceID(buf->instance_id); + if (instance_zs) + { + instance_zs->SendPacket(pack); + } + break; + } + case ServerOP_DzSetSecondsRemaining: + { + auto buf = reinterpret_cast(pack->pBuffer); + auto dz = DynamicZone::FindDynamicZoneByID(buf->dz_id); + if (dz) + { + dz->SetSecondsRemaining(buf->seconds); + } + break; + } + }; +} diff --git a/world/dynamic_zone.h b/world/dynamic_zone.h new file mode 100644 index 000000000..c95512260 --- /dev/null +++ b/world/dynamic_zone.h @@ -0,0 +1,42 @@ +#ifndef WORLD_DYNAMIC_ZONE_H +#define WORLD_DYNAMIC_ZONE_H + +#include "../common/eq_constants.h" +#include + +class ServerPacket; + +class DynamicZone +{ +public: + DynamicZone() = default; + DynamicZone(uint32_t id, uint32_t zone_id, uint32_t instance_id, uint32_t zone_version, + uint32_t start_time, uint32_t duration, DynamicZoneType type); + + static DynamicZone* FindDynamicZoneByID(uint32_t dz_id); + static void HandleZoneMessage(ServerPacket* pack); + + uint32_t GetID() const { return m_id; } + uint16_t GetInstanceID() const { return static_cast(m_instance_id); } + uint16_t GetZoneID() const { return static_cast(m_zone_id); } + uint32_t GetZoneVersion() const { return m_zone_version; } + std::chrono::system_clock::duration GetRemainingDuration() const { + return m_expire_time - std::chrono::system_clock::now(); } + + bool IsExpired() const { return m_expire_time < std::chrono::system_clock::now(); } + void SetSecondsRemaining(uint32_t seconds_remaining); + +private: + void SendZonesDurationUpdate(); + + uint32_t m_id = 0; + uint32_t m_instance_id = 0; + uint32_t m_zone_id = 0; + uint32_t m_zone_version = 0; + DynamicZoneType m_type{ DynamicZoneType::None }; + std::chrono::seconds m_duration; + std::chrono::time_point m_start_time; + std::chrono::time_point m_expire_time; +}; + +#endif diff --git a/world/expedition.cpp b/world/expedition.cpp index c2562b5c2..d983a82d0 100644 --- a/world/expedition.cpp +++ b/world/expedition.cpp @@ -30,28 +30,19 @@ extern ClientList client_list; extern ZSList zoneserver_list; -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, uint32_t leader_id +Expedition::Expedition(uint32_t expedition_id, const DynamicZone& dz, uint32_t leader_id ) : m_expedition_id(expedition_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), + m_dynamic_zone(dz), m_leader_id(leader_id), m_choose_leader_cooldown_timer{ static_cast(RuleI(Expedition, ChooseLeaderCooldownTime)) } { - m_expire_time = m_start_time + m_duration; m_warning_cooldown_timer.Enable(); } void Expedition::AddMember(uint32_t character_id) { - auto it = std::find_if(m_member_ids.begin(), m_member_ids.end(), - [&](uint32_t member_id) { return member_id == character_id; }); - - if (it == m_member_ids.end()) + if (!HasMember(character_id)) { m_member_ids.emplace_back(character_id); } @@ -126,16 +117,6 @@ void Expedition::SendZonesExpeditionDeleted() zoneserver_list.SendPacket(pack.get()); } -void Expedition::SendZonesDurationUpdate() -{ - uint32_t packsize = sizeof(ServerExpeditionUpdateDuration_Struct); - auto pack = std::make_unique(ServerOP_ExpeditionDzDuration, packsize); - auto packbuf = reinterpret_cast(pack->pBuffer); - packbuf->expedition_id = GetID(); - packbuf->new_duration_seconds = static_cast(m_duration.count()); - zoneserver_list.SendPacket(pack.get()); -} - void Expedition::SendZonesExpireWarning(uint32_t minutes_remaining) { uint32_t pack_size = sizeof(ServerExpeditionExpireWarning_Struct); @@ -156,41 +137,12 @@ void Expedition::SendZonesLeaderChanged() zoneserver_list.SendPacket(pack.get()); } -void Expedition::UpdateDzSecondsRemaining(uint32_t seconds_remaining) -{ - auto now = std::chrono::system_clock::now(); - auto update_time = std::chrono::seconds(seconds_remaining); - - auto current_remaining = m_expire_time - now; - if (current_remaining > update_time) // reduce only - { - LogExpeditionsDetail( - "Updating expedition [{}] dz instance [{}] seconds remaining to [{}]s", - GetID(), GetInstanceID(), seconds_remaining - ); - - // preserve original start time and adjust duration instead - m_expire_time = now + update_time; - m_duration = std::chrono::duration_cast(m_expire_time - m_start_time); - - ExpeditionDatabase::UpdateDzDuration(GetInstanceID(), static_cast(m_duration.count())); - - // update zone level caches and update the actual dz instance's timer - SendZonesDurationUpdate(); - } -} - -std::chrono::system_clock::duration Expedition::GetRemainingDuration() const -{ - return m_expire_time - std::chrono::system_clock::now(); -} - void Expedition::CheckExpireWarning() { if (m_warning_cooldown_timer.Check(false)) { using namespace std::chrono_literals; - auto remaining = GetRemainingDuration(); + auto remaining = GetDynamicZone().GetRemainingDuration(); if ((remaining > 14min && remaining < 15min) || (remaining > 4min && remaining < 5min) || (remaining > 0min && remaining < 1min)) diff --git a/world/expedition.h b/world/expedition.h index d166419bb..952abc1a0 100644 --- a/world/expedition.h +++ b/world/expedition.h @@ -21,6 +21,7 @@ #ifndef WORLD_EXPEDITION_H #define WORLD_EXPEDITION_H +#include "dynamic_zone.h" #include "../common/timer.h" #include #include @@ -30,8 +31,7 @@ class Expedition { public: Expedition() = default; - 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, uint32_t leader_id); + Expedition(uint32_t expedition_id, const DynamicZone& dz, uint32_t leader_id); void AddMember(uint32_t character_id); void RemoveMember(uint32_t character_id); @@ -39,38 +39,28 @@ public: void CheckExpireWarning(); void CheckLeader(); void ChooseNewLeader(); + DynamicZone& GetDynamicZone() { return m_dynamic_zone; } uint32_t GetID() const { return m_expedition_id; } - uint16_t GetInstanceID() const { return static_cast(m_dz_instance_id); } - uint16_t GetZoneID() const { return static_cast(m_dz_zone_id); } bool HasMember(uint32_t character_id); 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); bool SetNewLeader(uint32_t new_leader_id); void SetPendingDelete(bool pending) { m_pending_delete = pending; } - void UpdateDzSecondsRemaining(uint32_t seconds_remaining); - std::chrono::system_clock::duration GetRemainingDuration() const; private: void SendZonesLeaderChanged(); 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; uint32_t m_leader_id = 0; bool m_pending_delete = false; bool m_choose_leader_needed = false; Timer m_choose_leader_cooldown_timer; Timer m_warning_cooldown_timer; + DynamicZone m_dynamic_zone; std::vector m_member_ids; - std::chrono::seconds m_duration; - std::chrono::time_point m_start_time; - std::chrono::time_point m_expire_time; }; #endif diff --git a/world/expedition_database.cpp b/world/expedition_database.cpp index f9df67918..2f54d7f3d 100644 --- a/world/expedition_database.cpp +++ b/world/expedition_database.cpp @@ -81,6 +81,7 @@ std::vector ExpeditionDatabase::LoadExpeditions(uint32_t select_expe expeditions.dynamic_zone_id, instance_list.id, instance_list.zone, + instance_list.version, instance_list.start_time, instance_list.duration, expeditions.leader_id, @@ -112,20 +113,26 @@ std::vector ExpeditionDatabase::LoadExpeditions(uint32_t select_expe if (last_expedition_id != expedition_id) { - expeditions.emplace_back( - static_cast(strtoul(row[0], nullptr, 10)), // expedition_id + DynamicZone dynamic_zone{ 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 - static_cast(strtoul(row[6], nullptr, 10)) // leader_id + static_cast(strtoul(row[2], nullptr, 10)), // dz_instance_id + static_cast(strtoul(row[4], nullptr, 10)), // dz_zone_version + static_cast(strtoul(row[5], nullptr, 10)), // start_time + static_cast(strtoul(row[6], nullptr, 10)), // duration + DynamicZoneType::Expedition + }; + + expeditions.emplace_back( + expedition_id, + dynamic_zone, + static_cast(strtoul(row[7], nullptr, 10)) // leader_id ); } last_expedition_id = expedition_id; - uint32_t member_id = static_cast(strtoul(row[7], nullptr, 10)); + uint32_t member_id = static_cast(strtoul(row[8], nullptr, 10)); expeditions.back().AddMember(member_id); } } @@ -167,16 +174,6 @@ void ExpeditionDatabase::DeleteExpeditions(const std::vector& expediti } } -void ExpeditionDatabase::UpdateDzDuration(uint16_t instance_id, uint32_t new_duration) -{ - std::string query = fmt::format( - "UPDATE instance_list SET duration = {} WHERE id = {};", - new_duration, instance_id - ); - - database.QueryDatabase(query); -} - void ExpeditionDatabase::UpdateLeaderID(uint32_t expedition_id, uint32_t leader_id) { LogExpeditionsDetail("Updating leader [{}] for expedition [{}]", leader_id, expedition_id); diff --git a/world/expedition_database.h b/world/expedition_database.h index 16341210c..8342a292a 100644 --- a/world/expedition_database.h +++ b/world/expedition_database.h @@ -34,7 +34,6 @@ namespace ExpeditionDatabase void MoveMembersToSafeReturn(const std::vector& expedition_ids); void PurgeExpiredExpeditions(); void PurgeExpiredCharacterLockouts(); - void UpdateDzDuration(uint16_t instance_id, uint32_t new_duration); void UpdateLeaderID(uint32_t expedition_id, uint32_t leader_id); }; diff --git a/world/expedition_message.cpp b/world/expedition_message.cpp index 646e2272e..46ecfa9cc 100644 --- a/world/expedition_message.cpp +++ b/world/expedition_message.cpp @@ -104,12 +104,6 @@ void ExpeditionMessage::HandleZoneMessage(ServerPacket* pack) ExpeditionMessage::RequestInvite(pack); break; } - case ServerOP_ExpeditionSecondsRemaining: - { - auto buf = reinterpret_cast(pack->pBuffer); - expedition_state.SetSecondsRemaining(buf->expedition_id, buf->new_duration_seconds); - break; - } } } diff --git a/world/expedition_state.cpp b/world/expedition_state.cpp index 794cfeb36..c1cb0fc8c 100644 --- a/world/expedition_state.cpp +++ b/world/expedition_state.cpp @@ -38,6 +38,14 @@ Expedition* ExpeditionState::GetExpedition(uint32_t expedition_id) return (it != m_expeditions.end()) ? &(*it) : nullptr; } +Expedition* ExpeditionState::GetExpeditionByDynamicZoneID(uint32_t dz_id) +{ + auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(), + [&](Expedition& expedition) { return expedition.GetDynamicZone().GetID() == dz_id; }); + + return (it != m_expeditions.end()) ? &(*it) : nullptr; +} + void ExpeditionState::LoadActiveExpeditions() { BenchTimer benchmark; @@ -98,15 +106,6 @@ void ExpeditionState::RemoveAllMembers(uint32_t expedition_id) } } -void ExpeditionState::SetSecondsRemaining(uint32_t expedition_id, uint32_t seconds_remaining) -{ - auto expedition = GetExpedition(expedition_id); - if (expedition) - { - expedition->UpdateDzSecondsRemaining(seconds_remaining); - } -} - void ExpeditionState::Process() { if (!m_process_throttle_timer.Check()) @@ -120,13 +119,13 @@ void ExpeditionState::Process() { bool is_deleted = false; - if (it->IsEmpty() || it->IsExpired()) + if (it->IsEmpty() || it->GetDynamicZone().IsExpired()) { // don't delete expedition until its dz instance is empty. this prevents // an exploit where all members leave expedition and complete an event // before being kicked from removal timer. the lockout could never be // applied because the zone expedition cache was already invalidated. - auto dz_zoneserver = zoneserver_list.FindByInstanceID(it->GetInstanceID()); + auto dz_zoneserver = zoneserver_list.FindByInstanceID(it->GetDynamicZone().GetInstanceID()); if (!dz_zoneserver || dz_zoneserver->NumPlayers() == 0) { LogExpeditions("Expedition [{}] expired or empty, notifying zones and deleting", it->GetID()); @@ -137,7 +136,7 @@ void ExpeditionState::Process() if (it->IsEmpty() && !it->IsPendingDelete() && RuleB(Expedition, EmptyDzShutdownEnabled)) { - it->UpdateDzSecondsRemaining(RuleI(Expedition, EmptyDzShutdownDelaySeconds)); + it->GetDynamicZone().SetSecondsRemaining(RuleI(Expedition, EmptyDzShutdownDelaySeconds)); } it->SetPendingDelete(true); diff --git a/world/expedition_state.h b/world/expedition_state.h index 9d54dcec9..58b733989 100644 --- a/world/expedition_state.h +++ b/world/expedition_state.h @@ -35,12 +35,12 @@ class ExpeditionState public: void AddExpedition(uint32_t expedition_id); Expedition* GetExpedition(uint32_t expedition_id); + Expedition* GetExpeditionByDynamicZoneID(uint32_t dz_id); void LoadActiveExpeditions(); void MemberChange(uint32_t expedition_id, uint32_t character_id, bool remove); void Process(); void RemoveAllMembers(uint32_t expedition_id); void RemoveExpedition(uint32_t expedition_id); - void SetSecondsRemaining(uint32_t expedition_id, uint32_t seconds_remaining); private: std::vector m_expeditions; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 008c98073..3f0efbf19 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "ucs.h" #include "queryserv.h" #include "world_store.h" +#include "dynamic_zone.h" #include "expedition_message.h" extern ClientList client_list; @@ -1367,9 +1368,6 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_ExpeditionLockState: case ServerOP_ExpeditionMemberStatus: case ServerOP_ExpeditionReplayOnJoin: - case ServerOP_ExpeditionDzCompass: - case ServerOP_ExpeditionDzSafeReturn: - case ServerOP_ExpeditionDzZoneIn: case ServerOP_ExpeditionExpireWarning: { zoneserver_list.SendPacket(pack); @@ -1386,20 +1384,18 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_ExpeditionCharacterLockout: case ServerOP_ExpeditionSaveInvite: case ServerOP_ExpeditionRequestInvite: - case ServerOP_ExpeditionSecondsRemaining: { ExpeditionMessage::HandleZoneMessage(pack); break; } case ServerOP_DzCharacterChange: case ServerOP_DzRemoveAllCharacters: + case ServerOP_DzSetSecondsRemaining: + case ServerOP_DzSetCompass: + case ServerOP_DzSetSafeReturn: + case ServerOP_DzSetZoneIn: { - auto buf = reinterpret_cast(pack->pBuffer); - ZoneServer* instance_zs = zoneserver_list.FindByInstanceID(buf->instance_id); - if (instance_zs) - { - instance_zs->SendPacket(pack); - } + DynamicZone::HandleZoneMessage(pack); break; } default: diff --git a/zone/dynamic_zone.cpp b/zone/dynamic_zone.cpp index 72b42abba..9358f15a2 100644 --- a/zone/dynamic_zone.cpp +++ b/zone/dynamic_zone.cpp @@ -20,6 +20,7 @@ #include "dynamic_zone.h" #include "client.h" +#include "expedition.h" #include "worldserver.h" #include "zonedb.h" #include "../common/eqemu_logsys.h" @@ -37,20 +38,27 @@ DynamicZone::DynamicZone( } DynamicZone::DynamicZone( - std::string zone_shortname, uint32_t version, uint32_t duration, DynamicZoneType type + std::string zone_name, uint32_t version, uint32_t duration, DynamicZoneType type ) : - m_version(version), - m_duration(duration), - m_type(type) + DynamicZone(ZoneID(zone_name), version, duration, type) { - m_zone_id = ZoneID(zone_shortname.c_str()); - if (!m_zone_id) { - LogDynamicZones("Failed to get zone id for zone [{}]", zone_shortname); + LogDynamicZones("Failed to get zone id for zone [{}]", zone_name); } } +DynamicZone* DynamicZone::FindDynamicZoneByID(uint32_t dz_id) +{ + auto expedition = Expedition::FindCachedExpeditionByDynamicZoneID(dz_id); + if (expedition) + { + return &expedition->GetDynamicZone(); + } + // todo: other system caches + return nullptr; +} + std::unordered_map DynamicZone::LoadMultipleDzFromDatabase( const std::vector& dynamic_zone_ids) { @@ -443,12 +451,23 @@ void DynamicZone::SetCompass(const DynamicZoneLocation& location, bool update_db { m_compass = location; + if (m_on_compass_change) + { + m_on_compass_change(); + } + if (update_db) { SaveCompassToDatabase(); + SendWorldSetLocation(ServerOP_DzSetCompass, location); } } +void DynamicZone::SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db) +{ + SetCompass({ zone_id, x, y, z, 0.0f }, update_db); +} + void DynamicZone::SetSafeReturn(const DynamicZoneLocation& location, bool update_db) { m_safereturn = location; @@ -456,9 +475,15 @@ void DynamicZone::SetSafeReturn(const DynamicZoneLocation& location, bool update if (update_db) { SaveSafeReturnToDatabase(); + SendWorldSetLocation(ServerOP_DzSetSafeReturn, location); } } +void DynamicZone::SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db) +{ + SetSafeReturn({ zone_id, x, y, z, heading }, update_db); +} + void DynamicZone::SetZoneInLocation(const DynamicZoneLocation& location, bool update_db) { m_zonein = location; @@ -467,9 +492,15 @@ void DynamicZone::SetZoneInLocation(const DynamicZoneLocation& location, bool up if (update_db) { SaveZoneInLocationToDatabase(); + SendWorldSetLocation(ServerOP_DzSetZoneIn, location); } } +void DynamicZone::SetZoneInLocation(float x, float y, float z, float heading, bool update_db) +{ + SetZoneInLocation({ 0, x, y, z, heading }, update_db); +} + bool DynamicZone::IsCurrentZoneDzInstance() const { return (zone && zone->GetInstanceID() != 0 && zone->GetInstanceID() == GetInstanceID()); @@ -496,6 +527,17 @@ uint32_t DynamicZone::GetSecondsRemaining() const return 0; } +void DynamicZone::SetSecondsRemaining(uint32_t seconds_remaining) +{ + // async + constexpr uint32_t pack_size = sizeof(ServerDzSetDuration_Struct); + auto pack = std::make_unique(ServerOP_DzSetSecondsRemaining, pack_size); + auto buf = reinterpret_cast(pack->pBuffer); + buf->dz_id = GetID(); + buf->seconds = seconds_remaining; + worldserver.SendPacket(pack.get()); +} + void DynamicZone::SetUpdatedDuration(uint32_t new_duration) { // preserves original start time, just modifies duration and expire time @@ -511,6 +553,22 @@ void DynamicZone::SetUpdatedDuration(uint32_t new_duration) } } +void DynamicZone::SendWorldSetLocation(uint16_t server_opcode, const DynamicZoneLocation& location) +{ + uint32_t pack_size = sizeof(ServerDzLocation_Struct); + auto pack = std::make_unique(server_opcode, pack_size); + auto buf = reinterpret_cast(pack->pBuffer); + buf->dz_id = GetID(); + buf->sender_zone_id = zone ? zone->GetZoneID() : 0; + buf->sender_instance_id = zone ? zone->GetInstanceID() : 0; + buf->zone_id = location.zone_id; + buf->x = location.x; + buf->y = location.y; + buf->z = location.z; + buf->heading = location.heading; + worldserver.SendPacket(pack.get()); +} + void DynamicZone::HandleWorldMessage(ServerPacket* pack) { switch (pack->opcode) @@ -540,5 +598,41 @@ void DynamicZone::HandleWorldMessage(ServerPacket* pack) } break; } + case ServerOP_DzDurationUpdate: + { + auto buf = reinterpret_cast(pack->pBuffer); + auto dz = DynamicZone::FindDynamicZoneByID(buf->dz_id); + if (dz) + { + dz->SetUpdatedDuration(buf->seconds); + } + break; + } + case ServerOP_DzSetCompass: + case ServerOP_DzSetSafeReturn: + case ServerOP_DzSetZoneIn: + { + auto buf = reinterpret_cast(pack->pBuffer); + if (zone && !zone->IsZone(buf->sender_zone_id, buf->sender_instance_id)) + { + auto dz = DynamicZone::FindDynamicZoneByID(buf->dz_id); + if (dz) + { + if (pack->opcode == ServerOP_DzSetCompass) + { + dz->SetCompass(buf->zone_id, buf->x, buf->y, buf->z, false); + } + else if (pack->opcode == ServerOP_DzSetSafeReturn) + { + dz->SetSafeReturn(buf->zone_id, buf->x, buf->y, buf->z, buf->heading, false); + } + else if (pack->opcode == ServerOP_DzSetZoneIn) + { + dz->SetZoneInLocation(buf->x, buf->y, buf->z, buf->heading, false); + } + } + } + break; + } } } diff --git a/zone/dynamic_zone.h b/zone/dynamic_zone.h index 19d186bba..583dd6958 100644 --- a/zone/dynamic_zone.h +++ b/zone/dynamic_zone.h @@ -21,8 +21,10 @@ #ifndef DYNAMIC_ZONE_H #define DYNAMIC_ZONE_H +#include "../common/eq_constants.h" #include #include +#include #include #include #include @@ -30,16 +32,6 @@ class MySQLRequestRow; class ServerPacket; -enum class DynamicZoneType : uint8_t -{ - None = 0, - Expedition, - Tutorial, - Task, - Mission, // Shared Task - Quest -}; - struct DynamicZoneLocation { uint32_t zone_id = 0; @@ -62,6 +54,7 @@ public: DynamicZone(uint32_t dz_id) : m_id(dz_id) {} DynamicZone(DynamicZoneType type) : m_type(type) {} + static DynamicZone* FindDynamicZoneByID(uint32_t dz_id); static std::unordered_map LoadMultipleDzFromDatabase( const std::vector& dynamic_zone_ids); static void HandleWorldMessage(ServerPacket* pack); @@ -88,15 +81,20 @@ public: 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 RegisterOnCompassChange(const std::function& on_change) { m_on_compass_change = on_change; } void RemoveAllCharacters(bool enable_removal_timers = true); void RemoveCharacter(uint32_t character_id); void SaveInstanceMembersToDatabase(const std::vector& character_ids); void SendInstanceCharacterChange(uint32_t character_id, bool removed); void SetCompass(const DynamicZoneLocation& location, bool update_db = false); + void SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db = false); void SetLeaderName(const std::string& leader_name) { m_leader_name = leader_name; } void SetName(const std::string& name) { m_name = name; } void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false); + void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false); + void SetSecondsRemaining(uint32_t seconds_remaining); void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false); + void SetZoneInLocation(float x, float y, float z, float heading, bool update_db = false); void SetUpdatedDuration(uint32_t seconds); private: @@ -105,6 +103,7 @@ private: void SaveCompassToDatabase(); void SaveSafeReturnToDatabase(); void SaveZoneInLocationToDatabase(); + void SendWorldSetLocation(uint16_t server_opcode, const DynamicZoneLocation& location); uint32_t SaveToDatabase(); uint32_t m_id = 0; @@ -122,6 +121,7 @@ private: std::chrono::seconds m_duration; std::chrono::time_point m_start_time; std::chrono::time_point m_expire_time; + std::function m_on_compass_change; }; #endif diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 96ff0d45f..5bfecb8e4 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -69,6 +69,7 @@ void Expedition::SetDynamicZone(DynamicZone&& dz) dz.SetLeaderName(GetLeaderName()); m_dynamiczone = std::move(dz); + m_dynamiczone.RegisterOnCompassChange([this]() { SendCompassUpdateToZoneMembers(); }); } Expedition* Expedition::TryCreate( @@ -1631,24 +1632,6 @@ void Expedition::SendWorldMemberStatus(uint32_t character_id, ExpeditionMemberSt worldserver.SendPacket(pack.get()); } -void Expedition::SendWorldDzLocationUpdate(uint16_t server_opcode, const DynamicZoneLocation& location) -{ - uint32_t pack_size = sizeof(ServerDzLocation_Struct); - auto pack = std::make_unique(server_opcode, pack_size); - auto buf = reinterpret_cast(pack->pBuffer); - buf->owner_id = GetID(); - buf->dz_zone_id = m_dynamiczone.GetZoneID(); - buf->dz_instance_id = m_dynamiczone.GetInstanceID(); - buf->sender_zone_id = zone ? zone->GetZoneID() : 0; - buf->sender_instance_id = zone ? zone->GetInstanceID() : 0; - buf->zone_id = location.zone_id; - buf->x = location.x; - buf->y = location.y; - buf->z = location.z; - buf->heading = location.heading; - worldserver.SendPacket(pack.get()); -} - void Expedition::SendWorldMemberSwapped( const std::string& remove_char_name, uint32_t remove_char_id, const std::string& add_char_name, uint32_t add_char_id) { @@ -1716,16 +1699,6 @@ void Expedition::SendWorldCharacterLockout( worldserver.SendPacket(pack.get()); } -void Expedition::SendWorldSetSecondsRemaining(uint32_t seconds_remaining) -{ - uint32_t pack_size = sizeof(ServerExpeditionUpdateDuration_Struct); - auto pack = std::make_unique(ServerOP_ExpeditionSecondsRemaining, pack_size); - auto buf = reinterpret_cast(pack->pBuffer); - buf->expedition_id = GetID(); - buf->new_duration_seconds = seconds_remaining; - worldserver.SendPacket(pack.get()); -} - void Expedition::AddLockoutByCharacterID( uint32_t character_id, const std::string& expedition_name, const std::string& event_name, uint32_t seconds, const std::string& uuid) @@ -2007,32 +1980,6 @@ void Expedition::HandleWorldMessage(ServerPacket* pack) } break; } - case ServerOP_ExpeditionDzCompass: - case ServerOP_ExpeditionDzSafeReturn: - case ServerOP_ExpeditionDzZoneIn: - { - auto buf = reinterpret_cast(pack->pBuffer); - if (zone && !zone->IsZone(buf->sender_zone_id, buf->sender_instance_id)) - { - auto expedition = Expedition::FindCachedExpeditionByID(buf->owner_id); - if (expedition) - { - if (pack->opcode == ServerOP_ExpeditionDzCompass) - { - expedition->SetDzCompass(buf->zone_id, buf->x, buf->y, buf->z, false); - } - else if (pack->opcode == ServerOP_ExpeditionDzSafeReturn) - { - expedition->SetDzSafeReturn(buf->zone_id, buf->x, buf->y, buf->z, buf->heading, false); - } - else if (pack->opcode == ServerOP_ExpeditionDzZoneIn) - { - expedition->SetDzZoneInLocation(buf->x, buf->y, buf->z, buf->heading, false); - } - } - } - break; - } case ServerOP_ExpeditionCharacterLockout: { auto buf = reinterpret_cast(pack->pBuffer); @@ -2056,16 +2003,6 @@ void Expedition::HandleWorldMessage(ServerPacket* pack) } break; } - case ServerOP_ExpeditionDzDuration: - { - auto buf = reinterpret_cast(pack->pBuffer); - auto expedition = Expedition::FindCachedExpeditionByID(buf->expedition_id); - if (expedition) - { - expedition->UpdateDzDuration(buf->new_duration_seconds); - } - break; - } case ServerOP_ExpeditionExpireWarning: { auto buf = reinterpret_cast(pack->pBuffer); @@ -2079,11 +2016,8 @@ void Expedition::HandleWorldMessage(ServerPacket* pack) } } -void Expedition::SetDzCompass(uint32_t zone_id, float x, float y, float z, bool update_db) +void Expedition::SendCompassUpdateToZoneMembers() { - DynamicZoneLocation location{ zone_id, x, y, z, 0.0f }; - m_dynamiczone.SetCompass(location, update_db); - for (const auto& member : m_members) { Client* member_client = entity_list.GetClientByCharID(member.char_id); @@ -2092,52 +2026,6 @@ void Expedition::SetDzCompass(uint32_t zone_id, float x, float y, float z, bool member_client->SendDzCompassUpdate(); } } - - if (update_db) - { - SendWorldDzLocationUpdate(ServerOP_ExpeditionDzCompass, location); - } -} - -void Expedition::SetDzCompass(const std::string& zone_name, float x, float y, float z, bool update_db) -{ - auto zone_id = ZoneID(zone_name.c_str()); - SetDzCompass(zone_id, x, y, z, update_db); -} - -void Expedition::SetDzSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db) -{ - DynamicZoneLocation location{ zone_id, x, y, z, heading }; - - m_dynamiczone.SetSafeReturn(location, update_db); - - if (update_db) - { - SendWorldDzLocationUpdate(ServerOP_ExpeditionDzSafeReturn, location); - } -} - -void Expedition::SetDzSafeReturn(const std::string& zone_name, float x, float y, float z, float heading, bool update_db) -{ - auto zone_id = ZoneID(zone_name.c_str()); - SetDzSafeReturn(zone_id, x, y, z, heading, update_db); -} - -void Expedition::SetDzSecondsRemaining(uint32_t seconds_remaining) -{ - SendWorldSetSecondsRemaining(seconds_remaining); // async -} - -void Expedition::SetDzZoneInLocation(float x, float y, float z, float heading, bool update_db) -{ - DynamicZoneLocation location{ 0, x, y, z, heading }; - - m_dynamiczone.SetZoneInLocation(location, update_db); - - if (update_db) - { - SendWorldDzLocationUpdate(ServerOP_ExpeditionDzZoneIn, location); - } } bool Expedition::CanClientLootCorpse(Client* client, uint32_t npc_type_id, uint32_t spawn_id) diff --git a/zone/expedition.h b/zone/expedition.h index 4b9b1e940..c78864c6b 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -161,13 +161,6 @@ public: void DzQuit(Client* requester); void DzKickPlayers(Client* requester); - void SetDzCompass(uint32_t zone_id, float x, float y, float z, bool update_db = false); - void SetDzCompass(const std::string& zone_name, float x, float y, float z, bool update_db = false); - void SetDzSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false); - void SetDzSafeReturn(const std::string& zone_name, float x, float y, float z, float heading, bool update_db = false); - void SetDzSecondsRemaining(uint32_t seconds_remaining); - void SetDzZoneInLocation(float x, float y, float z, float heading, bool update_db = false); - static const int32_t REPLAY_TIMER_ID; static const int32_t EVENT_TIMER_ID; @@ -197,7 +190,7 @@ private: void SendMembersExpireWarning(uint32_t minutes); void SendNewMemberAddedToZoneMembers(const std::string& added_name); void SendUpdatesToZoneMembers(bool clear = false, bool message_on_clear = true); - void SendWorldDzLocationUpdate(uint16_t server_opcode, const DynamicZoneLocation& location); + void SendCompassUpdateToZoneMembers(); void SendWorldExpeditionUpdate(uint16_t server_opcode); void SendWorldAddPlayerInvite(const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name, bool pending = false); @@ -209,12 +202,10 @@ private: void SendWorldMemberStatus(uint32_t character_id, ExpeditionMemberStatus status); void SendWorldMemberSwapped(const std::string& remove_char_name, uint32_t remove_char_id, const std::string& add_char_name, uint32_t add_char_id); - void SendWorldSetSecondsRemaining(uint32_t seconds_remaining); void SendWorldSettingChanged(uint16_t server_opcode, bool setting_value); void SetDynamicZone(DynamicZone&& dz); void TryAddClient(Client* add_client, const std::string& inviter_name, const std::string& swap_remove_name, Client* leader_client = nullptr); - void UpdateDzDuration(uint32_t new_duration) { m_dynamiczone.SetUpdatedDuration(new_duration); } void UpdateMemberStatus(uint32_t update_character_id, ExpeditionMemberStatus status); ExpeditionMember GetMemberData(uint32_t character_id); diff --git a/zone/lua_expedition.cpp b/zone/lua_expedition.cpp index a7ac929c0..1bd872cc2 100644 --- a/zone/lua_expedition.cpp +++ b/zone/lua_expedition.cpp @@ -168,7 +168,7 @@ bool Lua_Expedition::IsLocked() { void Lua_Expedition::RemoveCompass() { Lua_Safe_Call_Void(); - self->SetDzCompass(0, 0, 0, 0, true); + self->GetDynamicZone().SetCompass(0, 0, 0, 0, true); } void Lua_Expedition::RemoveLockout(std::string event_name) { @@ -178,12 +178,12 @@ void Lua_Expedition::RemoveLockout(std::string event_name) { void Lua_Expedition::SetCompass(uint32_t zone_id, float x, float y, float z) { Lua_Safe_Call_Void(); - self->SetDzCompass(zone_id, x, y, z, true); + self->GetDynamicZone().SetCompass(zone_id, x, y, z, true); } void Lua_Expedition::SetCompass(std::string zone_name, float x, float y, float z) { Lua_Safe_Call_Void(); - self->SetDzCompass(zone_name, x, y, z, true); + self->GetDynamicZone().SetCompass(ZoneID(zone_name), x, y, z, true); } void Lua_Expedition::SetLocked(bool lock_expedition) { @@ -218,23 +218,23 @@ void Lua_Expedition::SetReplayLockoutOnMemberJoin(bool enable) { void Lua_Expedition::SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading) { Lua_Safe_Call_Void(); - self->SetDzSafeReturn(zone_id, x, y, z, heading, true); + self->GetDynamicZone().SetSafeReturn(zone_id, x, y, z, heading, true); } void Lua_Expedition::SetSafeReturn(std::string zone_name, float x, float y, float z, float heading) { Lua_Safe_Call_Void(); - self->SetDzSafeReturn(zone_name, x, y, z, heading, true); + self->GetDynamicZone().SetSafeReturn(ZoneID(zone_name), x, y, z, heading, true); } void Lua_Expedition::SetSecondsRemaining(uint32_t seconds_remaining) { Lua_Safe_Call_Void(); - self->SetDzSecondsRemaining(seconds_remaining); + self->GetDynamicZone().SetSecondsRemaining(seconds_remaining); } void Lua_Expedition::SetZoneInLocation(float x, float y, float z, float heading) { Lua_Safe_Call_Void(); - self->SetDzZoneInLocation(x, y, z, heading, true); + self->GetDynamicZone().SetZoneInLocation(x, y, z, heading, true); } void Lua_Expedition::UpdateLockoutDuration(std::string event_name, uint32_t duration) { diff --git a/zone/perl_expedition.cpp b/zone/perl_expedition.cpp index e7b477636..3095c3770 100644 --- a/zone/perl_expedition.cpp +++ b/zone/perl_expedition.cpp @@ -407,7 +407,7 @@ XS(XS_Expedition_RemoveCompass) { Expedition* THIS = nullptr; VALIDATE_THIS_IS_EXPEDITION; - THIS->SetDzCompass(0, 0, 0, 0, true); + THIS->GetDynamicZone().SetCompass(0, 0, 0, 0, true); XSRETURN_EMPTY; } @@ -446,12 +446,12 @@ XS(XS_Expedition_SetCompass) { if (SvTYPE(ST(1)) == SVt_PV) { std::string zone_name(SvPV_nolen(ST(1))); - THIS->SetDzCompass(zone_name, x, y, z, true); + THIS->GetDynamicZone().SetCompass(ZoneID(zone_name), x, y, z, true); } else if (SvTYPE(ST(1)) == SVt_IV) { uint32_t zone_id = static_cast(SvUV(ST(1))); - THIS->SetDzCompass(zone_id, x, y, z, true); + THIS->GetDynamicZone().SetCompass(zone_id, x, y, z, true); } else { @@ -556,12 +556,12 @@ XS(XS_Expedition_SetSafeReturn) { if (SvTYPE(ST(1)) == SVt_PV) { std::string zone_name(SvPV_nolen(ST(1))); - THIS->SetDzSafeReturn(zone_name, x, y, z, heading, true); + THIS->GetDynamicZone().SetSafeReturn(ZoneID(zone_name), x, y, z, heading, true); } else if (SvTYPE(ST(1)) == SVt_IV) { uint32_t zone_id = static_cast(SvUV(ST(1))); - THIS->SetDzSafeReturn(zone_id, x, y, z, heading, true); + THIS->GetDynamicZone().SetSafeReturn(zone_id, x, y, z, heading, true); } else { @@ -582,7 +582,7 @@ XS(XS_Expedition_SetSecondsRemaining) { VALIDATE_THIS_IS_EXPEDITION; uint32_t seconds_remaining = static_cast(SvUV(ST(1))); - THIS->SetDzSecondsRemaining(seconds_remaining); + THIS->GetDynamicZone().SetSecondsRemaining(seconds_remaining); XSRETURN_EMPTY; } @@ -602,7 +602,7 @@ XS(XS_Expedition_SetZoneInLocation) { float z = static_cast(SvNV(ST(3))); float heading = static_cast(SvNV(ST(4))); - THIS->SetDzZoneInLocation(x, y, z, heading, true); + THIS->GetDynamicZone().SetZoneInLocation(x, y, z, heading, true); XSRETURN_EMPTY; } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index a838a75cb..34994d88a 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -2900,10 +2900,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_ExpeditionGetOnlineMembers: case ServerOP_ExpeditionDzAddPlayer: case ServerOP_ExpeditionDzMakeLeader: - case ServerOP_ExpeditionDzCompass: - case ServerOP_ExpeditionDzSafeReturn: - case ServerOP_ExpeditionDzZoneIn: - case ServerOP_ExpeditionDzDuration: case ServerOP_ExpeditionCharacterLockout: case ServerOP_ExpeditionExpireWarning: { @@ -2912,6 +2908,10 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } case ServerOP_DzCharacterChange: case ServerOP_DzRemoveAllCharacters: + case ServerOP_DzDurationUpdate: + case ServerOP_DzSetCompass: + case ServerOP_DzSetSafeReturn: + case ServerOP_DzSetZoneIn: { DynamicZone::HandleWorldMessage(pack); break;