From 9ed31bd63e56cbc6a4d82a491bd08576d108a73c Mon Sep 17 00:00:00 2001
From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com>
Date: Sun, 24 Aug 2025 08:50:16 -0400
Subject: [PATCH] refactor(Core/Packets): Rewrite various query packets to
modern class. (#22719)
---
src/server/game/Handlers/QueryHandler.cpp | 59 ++++++-------
src/server/game/Handlers/TicketHandler.cpp | 2 +-
src/server/game/Server/Packets/AllPackets.h | 1 +
.../game/Server/Packets/QueryPackets.cpp | 58 +++++++++++++
src/server/game/Server/Packets/QueryPackets.h | 87 +++++++++++++++++++
src/server/game/Server/Protocol/Opcodes.cpp | 2 +-
src/server/game/Server/WorldSession.h | 15 +++-
7 files changed, 184 insertions(+), 40 deletions(-)
create mode 100644 src/server/game/Server/Packets/QueryPackets.cpp
create mode 100644 src/server/game/Server/Packets/QueryPackets.h
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 0666af71c..604977301 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -24,6 +24,7 @@
#include "Opcodes.h"
#include "Pet.h"
#include "Player.h"
+#include "QueryPackets.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
@@ -32,62 +33,55 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
{
CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid);
- WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
- data << guid.WriteAsPacked();
+ WorldPackets::Query::NameQueryResponse nameQueryResponse;
+ nameQueryResponse.Guid = guid.WriteAsPacked();
if (!playerData)
{
- data << uint8(1); // name unknown
- SendPacket(&data);
+ nameQueryResponse.NameUnknown = true;
+ SendPacket(nameQueryResponse.Write());
return;
}
Player* player = ObjectAccessor::FindConnectedPlayer(guid);
- data << uint8(0); // name known
- data << playerData->Name; // played name
- data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds)
- data << uint8(player ? player->getRace() : playerData->Race);
- data << uint8(playerData->Sex);
- data << uint8(playerData->Class);
+ nameQueryResponse.NameUnknown = false;
+ nameQueryResponse.Name = playerData->Name;
+ nameQueryResponse.Race = player ? player->getRace() : playerData->Race;
+ nameQueryResponse.Sex = player ? player->getGender() : playerData->Sex;
+ nameQueryResponse.Class = player ? player->getClass() : playerData->Class;
- // pussywizard: optimization
- /*Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr))
{
- data << uint8(1); // Name is declined
- for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
- data << names->name[i];
+ nameQueryResponse.Declined = true;
+ nameQueryResponse.DeclinedNames = *names;
}
- else*/
- data << uint8(0); // Name is not declined
+ else
+ nameQueryResponse.Declined = false;
- SendPacket(&data);
+ SendPacket(nameQueryResponse.Write());
}
-void WorldSession::HandleNameQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet)
{
- ObjectGuid guid;
- recvData >> guid;
-
// This is disable by default to prevent lots of console spam
// LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid);
- SendNameQueryOpcode(guid);
+ SendNameQueryOpcode(packet.Guid);
}
-void WorldSession::HandleQueryTimeOpcode(WorldPacket& /*recvData*/)
+void WorldSession::HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& /*packet*/)
{
- SendQueryTimeResponse();
+ SendTimeQueryResponse();
}
-void WorldSession::SendQueryTimeResponse()
+void WorldSession::SendTimeQueryResponse()
{
auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime();
- WorldPacket data(SMSG_QUERY_TIME_RESPONSE, 4 + 4);
- data << uint32(GameTime::GetGameTime().count());
- data << uint32(timeResponse.count());
- SendPacket(&data);
+ WorldPackets::Query::TimeQueryResponse timeQueryResponse;
+ timeQueryResponse.ServerTime = GameTime::GetGameTime().count();
+ timeQueryResponse.TimeResponse = timeResponse.count();
+ SendPacket(timeQueryResponse.Write());
}
/// Only _static_ data is sent in this packet !!!
@@ -402,13 +396,10 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData)
}
}
-void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData)
+void WorldSession::HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& /*packet*/)
{
LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");
- uint32 unk;
- recvData >> unk;
-
WorldPacket data(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4 + 4 + 4 + 4);
data << float(0);
data << float(0);
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index eb6243b21..089546aa5 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -172,7 +172,7 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket& /*recv_data*/)
void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket& /*recv_data*/)
{
- SendQueryTimeResponse();
+ SendTimeQueryResponse();
if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h
index 1e3457e1d..30aecbb6f 100644
--- a/src/server/game/Server/Packets/AllPackets.h
+++ b/src/server/game/Server/Packets/AllPackets.h
@@ -27,6 +27,7 @@
#include "LFGPackets.h"
#include "MiscPackets.h"
#include "PetPackets.h"
+#include "QueryPackets.h"
#include "TotemPackets.h"
#include "WorldStatePackets.h"
diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp
new file mode 100644
index 000000000..6efa96275
--- /dev/null
+++ b/src/server/game/Server/Packets/QueryPackets.cpp
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation; either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "QueryPackets.h"
+
+void WorldPackets::Query::NameQuery::Read()
+{
+ _worldPacket >> Guid;
+}
+
+WorldPacket const* WorldPackets::Query::NameQueryResponse::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << NameUnknown;
+ if (NameUnknown)
+ return &_worldPacket;
+
+ _worldPacket << Name;
+ _worldPacket << RealmName;
+ _worldPacket << Race;
+ _worldPacket << Sex;
+ _worldPacket << Class;
+ _worldPacket << Declined;
+ if (Declined)
+ {
+ for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
+ _worldPacket << DeclinedNames.name[i];
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Query::TimeQueryResponse::Write()
+{
+ _worldPacket << ServerTime;
+ _worldPacket << TimeResponse;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Query::CorpseMapPositionQuery::Read()
+{
+ _worldPacket >> unk;
+}
diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h
new file mode 100644
index 000000000..85d7a76ce
--- /dev/null
+++ b/src/server/game/Server/Packets/QueryPackets.h
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation; either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef QueryPackets_h__
+#define QueryPackets_h__
+
+#include "Packet.h"
+#include "Unit.h"
+
+namespace WorldPackets
+{
+ namespace Query
+ {
+ class NameQuery final : public ClientPacket
+ {
+ public:
+ NameQuery(WorldPacket&& packet) : ClientPacket(CMSG_NAME_QUERY, std::move(packet)) {}
+
+ void Read() override;
+
+ ObjectGuid Guid;
+ };
+
+ class NameQueryResponse final : public ServerPacket
+ {
+ public:
+ NameQueryResponse() : ServerPacket(SMSG_NAME_QUERY_RESPONSE, 8 + 1 + 1 + 1 + 1 + 1 + 10) {}
+
+ WorldPacket const* Write() override;
+
+ PackedGuid Guid;
+ uint8 NameUnknown = false;
+ std::string_view Name;
+ std::string_view RealmName = ""; // Only set for cross realm interaction (such as Battlegrounds)
+ uint8 Race = RACE_NONE;
+ uint8 Sex = GENDER_MALE;
+ uint8 Class = CLASS_NONE;
+ uint8 Declined = false;
+ DeclinedName DeclinedNames;
+ };
+
+ class TimeQuery final : public ClientPacket
+ {
+ public:
+ TimeQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_TIME, std::move(packet)) {}
+
+ void Read() override {};
+ };
+
+ class TimeQueryResponse final : public ServerPacket
+ {
+ public:
+ TimeQueryResponse() : ServerPacket(SMSG_QUERY_TIME_RESPONSE, 4 + 4) {}
+
+ WorldPacket const* Write() override;
+
+ uint32 ServerTime;
+ uint32 TimeResponse;
+ };
+
+ class CorpseMapPositionQuery final : public ClientPacket
+ {
+ public:
+ CorpseMapPositionQuery(WorldPacket&& packet) : ClientPacket(CMSG_CORPSE_MAP_POSITION_QUERY, std::move(packet)) {}
+
+ void Read() override;
+
+ uint32 unk;
+ };
+ }
+}
+
+#endif // QueryPackets_h__
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 85bcb4186..bc12f7764 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -590,7 +590,7 @@ void OpcodeTable::Initialize()
/*0x1CB*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_NEVER);
/*0x1CC*/ DEFINE_HANDLER(CMSG_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePlayedTime );
/*0x1CD*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER);
- /*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQueryTimeOpcode );
+ /*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeQueryOpcode );
/*0x1CF*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER);
/*0x1D0*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_NEVER);
/*0x1D1*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 9e570f9b0..032e18abf 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -160,6 +160,13 @@ namespace WorldPackets
class PetSpellAutocast;
class RequestPetInfo;
}
+
+ namespace Query
+ {
+ class NameQuery;
+ class TimeQuery;
+ class CorpseMapPositionQuery;
+ }
}
enum AccountDataType
@@ -371,7 +378,7 @@ public:
}
void SendSetPhaseShift(uint32 phaseShift);
- void SendQueryTimeResponse();
+ void SendTimeQueryResponse();
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0);
void SendClientCacheVersion(uint32 version);
@@ -661,9 +668,9 @@ public: // opcodes handlers
void HandleGameObjectUseOpcode(WorldPacket& recPacket);
void HandleGameobjectReportUse(WorldPacket& recvPacket);
- void HandleNameQueryOpcode(WorldPacket& recvPacket);
+ void HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet);
- void HandleQueryTimeOpcode(WorldPacket& recvPacket);
+ void HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& packet);
void HandleCreatureQueryOpcode(WorldPacket& recvPacket);
@@ -863,7 +870,7 @@ public: // opcodes handlers
void HandleReclaimCorpseOpcode(WorldPacket& recvPacket);
void HandleCorpseQueryOpcode(WorldPacket& recvPacket);
- void HandleCorpseMapPositionQuery(WorldPacket& recvPacket);
+ void HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& packet);
void HandleResurrectResponseOpcode(WorldPacket& recvPacket);
void HandleSummonResponseOpcode(WorldPacket& recvData);