From c8a7066d0eff1b3be7a479bac3568c258736caf1 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Sat, 29 Mar 2025 19:50:44 -0500 Subject: [PATCH] [Performance] Send Smarter Emote Packets (#4818) --- world/clientlist.cpp | 33 +++++++++++++++++++++++ world/clientlist.h | 1 + world/zonelist.cpp | 64 ++++++++++++++++++++++++++++++++++---------- world/zonelist.h | 1 + world/zoneserver.cpp | 8 +++++- 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 75a53dd00..72234731b 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -1886,3 +1886,36 @@ std::vector ClientList::GetGuildZoneServers(uint32 guild_id) return zone_server_ids; } + +std::vector ClientList::GetZoneServersWithGMs() +{ + std::vector zone_server_ids; + std::unordered_set seen_ids; + LinkedListIterator iterator(clientlist); + + iterator.Reset(); + while (iterator.MoreElements()) { + ClientListEntry *cle = iterator.GetData(); + + if (cle->Online() != CLE_Status::InZone) { + iterator.Advance(); + continue; + } + + if (!cle->Server()) { + iterator.Advance(); + continue; + } + + if (cle->Admin() > 0) { + uint32_t id = cle->Server()->GetID(); + if (seen_ids.insert(id).second) { + zone_server_ids.emplace_back(id); + } + } + + iterator.Advance(); + } + + return zone_server_ids; +} diff --git a/world/clientlist.h b/world/clientlist.h index 8fb6958a7..b805ade6a 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -61,6 +61,7 @@ public: void CLEKeepAlive(uint32 numupdates, uint32* wid); void CLEAdd(uint32 login_server_id, const char* login_server_name, const char* login_name, const char* login_key, int16 world_admin = AccountStatus::Player, uint32 ip_address = 0, uint8 is_local=0); std::vector GetGuildZoneServers(uint32 guild_id); + std::vector GetZoneServersWithGMs(); void UpdateClientGuild(uint32 char_id, uint32 guild_id); bool IsAccountInGame(uint32 iLSID); diff --git a/world/zonelist.cpp b/world/zonelist.cpp index bda4e232a..0b74006be 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -517,19 +517,27 @@ void ZSList::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_mins SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, buffer); } -void ZSList::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message) { - if (!message) +void ZSList::SendEmoteMessageRaw( + const char *to, + uint32 to_guilddbid, + int16 to_minstatus, + uint32 type, + const char *message +) +{ + if (!message) { return; + } auto pack = new ServerPacket; - pack->opcode = ServerOP_EmoteMessage; - pack->size = sizeof(ServerEmoteMessage_Struct) + strlen(message) + 1; + pack->opcode = ServerOP_EmoteMessage; + pack->size = sizeof(ServerEmoteMessage_Struct) + strlen(message) + 1; pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); - ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*)pack->pBuffer; + ServerEmoteMessage_Struct *sem = (ServerEmoteMessage_Struct *) pack->pBuffer; if (to) { - strcpy((char *)sem->to, to); + strcpy((char *) sem->to, to); } else { sem->to[0] = 0; @@ -537,22 +545,37 @@ void ZSList::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_m sem->guilddbid = to_guilddbid; sem->minstatus = to_minstatus; - sem->type = type; + sem->type = type; strcpy(&sem->message[0], message); - char tempto[64] = { 0 }; - if (to) + char tempto[64] = {0}; + if (to) { strn0cpy(tempto, to, 64); + } if (tempto[0] == 0) { - SendPacket(pack); + if (to_guilddbid > 0) { + SendPacketToZonesWithGuild(to_guilddbid, pack); + } + else if (to_minstatus > 0) { + SendPacketToZonesWithGMs(pack); + } else { + SendPacket(pack); + } } else { - ZoneServer* zs = FindByName(to); - - if (zs != 0) + ZoneServer *zs = FindByName(to); + if (zs) { zs->SendPacket(pack); - else + } + else if (to_guilddbid > 0) { + SendPacketToZonesWithGuild(to_guilddbid, pack); + } + else if (to_minstatus > 0) { + SendPacketToZonesWithGMs(pack); + } + else { SendPacket(pack); + } } delete pack; } @@ -887,6 +910,19 @@ bool ZSList::SendPacketToZonesWithGuild(uint32 guild_id, ServerPacket* pack) return true; } +bool ZSList::SendPacketToZonesWithGMs(ServerPacket* pack) +{ + for (auto const &z: zone_server_list) { + for (auto const &server_id: client_list.GetZoneServersWithGMs()) { + if (z->GetID() == server_id && z->GetZoneID() > 0) { + z->SendPacket(pack); + } + } + } + + return true; +} + void ZSList::SendServerReload(ServerReload::Type type, uchar *packet) { static auto pack = ServerPacket(ServerOP_ServerReloadRequest, sizeof(ServerReload::Request)); diff --git a/world/zonelist.h b/world/zonelist.h index d12b247ae..ed08e18a2 100644 --- a/world/zonelist.h +++ b/world/zonelist.h @@ -30,6 +30,7 @@ public: bool SendPacket(uint32 zoneid, ServerPacket *pack); bool SendPacket(uint32 zoneid, uint16 instanceid, ServerPacket *pack); bool SendPacketToZonesWithGuild(uint32 guild_id, ServerPacket *pack); + bool SendPacketToZonesWithGMs(ServerPacket *pack); bool SendPacketToBootedZones(ServerPacket* pack); bool SetLockedZone(uint16 iZoneID, bool iLock); diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 4fcdbccd5..1e8dd9f81 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -571,7 +571,13 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { ); } } - zoneserver_list.SendPacket(pack); + if (scm->guilddbid > 0) { + zoneserver_list.SendPacketToZonesWithGuild(scm->guilddbid, pack); + } else if (scm->chan_num == ChatChannel_GMSAY) { + zoneserver_list.SendPacketToZonesWithGMs(pack); + } else { + zoneserver_list.SendPacket(pack); + } } break;