From da5d4b9830f8d0f22837f7eb08ad9539b9a525f1 Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Sun, 4 Oct 2020 20:17:50 -0400 Subject: [PATCH] Send all members expedition expire warnings All expedition members are notified not just those in dz This will only work if the dz is running. It might make more sense to move this to client or world processing so members are notified even if the zone instance isn't running --- common/servertalk.h | 6 ++++++ world/zoneserver.cpp | 1 + zone/expedition.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ zone/expedition.h | 3 +++ zone/worldserver.cpp | 1 + zone/zone.cpp | 22 +++++++++++++++++----- 6 files changed, 73 insertions(+), 5 deletions(-) diff --git a/common/servertalk.h b/common/servertalk.h index fc1881d88..cb541bd6c 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -163,6 +163,7 @@ #define ServerOP_ExpeditionDzDuration 0x0413 #define ServerOP_ExpeditionLockoutDuration 0x0414 #define ServerOP_ExpeditionSecondsRemaining 0x0415 +#define ServerOP_ExpeditionExpireWarning 0x0416 #define ServerOP_DzCharacterChange 0x0450 #define ServerOP_DzRemoveAllCharacters 0x0451 @@ -2088,6 +2089,11 @@ struct ServerExpeditionUpdateDuration_Struct { uint32_t new_duration_seconds; }; +struct ServerExpeditionExpireWarning_Struct { + uint32_t expedition_id; + uint32_t minutes_remaining; +}; + struct ServerDzCommand_Struct { uint32 expedition_id; uint8 is_char_online; // 0: target name is offline, 1: online diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index a38b79bf2..e1beff363 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1371,6 +1371,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_ExpeditionDzCompass: case ServerOP_ExpeditionDzSafeReturn: case ServerOP_ExpeditionDzZoneIn: + case ServerOP_ExpeditionExpireWarning: { zoneserver_list.SendPacket(pack); break; diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 20b2ebaf1..f2fcd808a 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -1436,6 +1436,15 @@ void Expedition::SendWorldPendingInvite(const ExpeditionInvite& invite, const st SendWorldAddPlayerInvite(invite.inviter_name, invite.swap_remove_name, add_name, true); } +std::unique_ptr Expedition::CreateExpireWarningPacket(uint32_t minutes_remaining) +{ + uint32_t outsize = sizeof(ExpeditionExpireWarning); + auto outapp = std::unique_ptr(new EQApplicationPacket(OP_DzExpeditionEndsWarning, outsize)); + auto buf = reinterpret_cast(outapp->pBuffer); + buf->minutes_remaining = minutes_remaining; + return outapp; +} + std::unique_ptr Expedition::CreateInfoPacket(bool clear) { uint32_t outsize = sizeof(ExpeditionInfo_Struct); @@ -1733,6 +1742,16 @@ void Expedition::SendWorldSetSecondsRemaining(uint32_t seconds_remaining) worldserver.SendPacket(pack.get()); } +void Expedition::SendWorldExpireWarning(uint32_t minutes_remaining) +{ + uint32_t pack_size = sizeof(ServerExpeditionExpireWarning_Struct); + auto pack = std::unique_ptr(new ServerPacket(ServerOP_ExpeditionExpireWarning, pack_size)); + auto buf = reinterpret_cast(pack->pBuffer); + buf->expedition_id = GetID(); + buf->minutes_remaining = minutes_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) @@ -2075,6 +2094,16 @@ void Expedition::HandleWorldMessage(ServerPacket* pack) } break; } + case ServerOP_ExpeditionExpireWarning: + { + auto buf = reinterpret_cast(pack->pBuffer); + auto expedition = Expedition::FindCachedExpeditionByID(buf->expedition_id); + if (expedition) + { + expedition->SendMembersExpireWarning(buf->minutes_remaining); + } + break; + } } } @@ -2238,3 +2267,19 @@ std::vector Expedition::GetExpeditionLockoutsByCharacter return lockouts; } + +void Expedition::SendMembersExpireWarning(uint32_t minutes_remaining) +{ + // expeditions warn members in all zones not just the dz + auto outapp = CreateExpireWarningPacket(minutes_remaining); + for (const auto& member : m_members) + { + Client* member_client = entity_list.GetClientByCharID(member.char_id); + if (member_client) + { + member_client->QueuePacket(outapp.get()); + member_client->MessageString(Chat::Yellow, EXPEDITION_MIN_REMAIN, + fmt::format_int(minutes_remaining).c_str()); + } + } +} diff --git a/zone/expedition.h b/zone/expedition.h index b5c33570f..d8efb3052 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -142,6 +142,7 @@ public: void SetLootEventBySpawnID(uint32_t spawn_id, const std::string& event_name); void SendClientExpeditionInfo(Client* client); + void SendWorldExpireWarning(uint32_t minutes); void SendWorldPendingInvite(const ExpeditionInvite& invite, const std::string& add_name); void DzAddPlayer(Client* requester, const std::string& add_char_name, const std::string& swap_remove_name = {}); @@ -187,6 +188,7 @@ private: Client* client, const std::string& inviter_name, const std::string& swap_remove_name); void SendLeaderMessage(Client* leader_client, uint16_t chat_type, uint32_t string_id, const std::initializer_list& args = {}); + void SendMembersExpireWarning(uint32_t minutes); void SendUpdatesToZoneMembers(bool clear = false, bool message_on_clear = true); void SendWorldDzLocationUpdate(uint16_t server_opcode, const DynamicZoneLocation& location); void SendWorldExpeditionUpdate(uint16_t server_opcode); @@ -211,6 +213,7 @@ private: ExpeditionMember GetMemberData(uint32_t character_id); ExpeditionMember GetMemberData(const std::string& character_name); + std::unique_ptr CreateExpireWarningPacket(uint32_t minutes_remaining); std::unique_ptr CreateInfoPacket(bool clear = false); std::unique_ptr CreateInvitePacket(const std::string& inviter_name, const std::string& swap_remove_name); std::unique_ptr CreateMemberListPacket(bool clear = false); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index c144aadf6..920a3d958 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -2909,6 +2909,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_ExpeditionDzZoneIn: case ServerOP_ExpeditionDzDuration: case ServerOP_ExpeditionCharacterLockout: + case ServerOP_ExpeditionExpireWarning: { Expedition::HandleWorldMessage(pack); break; diff --git a/zone/zone.cpp b/zone/zone.cpp index 3d46a0009..a4bd6cabe 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1508,19 +1508,31 @@ bool Zone::Process() { if(Instance_Warning_timer == nullptr) { uint32 rem_time = Instance_Timer->GetRemainingTime(); + uint32_t minutes_warning = 0; if(rem_time < 60000 && rem_time > 55000) { - entity_list.ExpeditionWarning(1); - Instance_Warning_timer = new Timer(10000); + minutes_warning = 1; } else if(rem_time < 300000 && rem_time > 295000) { - entity_list.ExpeditionWarning(5); - Instance_Warning_timer = new Timer(10000); + minutes_warning = 5; } else if(rem_time < 900000 && rem_time > 895000) { - entity_list.ExpeditionWarning(15); + minutes_warning = 15; + } + + if (minutes_warning > 0) + { + auto expedition = Expedition::FindCachedExpeditionByZoneInstance(GetZoneID(), GetInstanceID()); + if (expedition) + { + expedition->SendWorldExpireWarning(minutes_warning); + } + else + { + entity_list.ExpeditionWarning(minutes_warning); + } Instance_Warning_timer = new Timer(10000); } }