diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-10-30 14:40:36 +0100 |
---|---|---|
committer | Ovahlord <dreadkiller@gmx.de> | 2025-04-05 00:55:05 +0200 |
commit | ab54b2d821c5c8ca3583d37692d34aa8fa05fdf2 (patch) | |
tree | ebd22881f5120ad728e5e22d927f6e92cdd8220a | |
parent | a54754caa72f3413bd0b552efeb1d583c0a08f3f (diff) |
Core/PacketIO: ported opcode size changes from ac7a95b45ca239d91b3daa8e2f77376382b092d2
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.h | 86 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/PacketLog.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 4 |
10 files changed, 109 insertions, 48 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a0c8d2c0483..63130b64ee6 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -25872,7 +25872,7 @@ void Player::RemoveGlyph(uint8 index) SendTalentsInfoData(); } -void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode) +void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint32 opcode) { if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == CMSG_MOVE_FALL_LAND) SetFallInformation(minfo.jump.fallTime, minfo.pos.GetPositionZ()); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 4ddb5fc2228..bdb9d6295d2 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2429,7 +2429,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> /*********************************************************/ /*** VARIOUS SYSTEMS ***/ /*********************************************************/ - void UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode); + void UpdateFallInformationIfNeed(MovementInfo const& minfo, uint32 opcode); // only changed for direct client control (possess, vehicle etc.), not stuff you control using pet commands WorldObject* m_seer; void SetFallInformation(uint32 time, float z); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index b92384d3919..32f0ad8b7b2 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1064,6 +1064,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder) pCurrChar->SetGuildLevel(0); } + SendAuctionFavoriteList(); + pCurrChar->GetSession()->GetBattlePetMgr()->SendJournalLockStatus(); pCurrChar->SendInitialPacketsBeforeAddToMap(); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 29118270a17..7e04f22050f 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -57,15 +57,16 @@ bool OpcodeTable::ValidateClientOpcode(OpcodeClient opcode, char const* name) co return false; } - if (opcode < MIN_CMSG_OPCODE_NUMBER || opcode > MAX_CMSG_OPCODE_NUMBER) + std::ptrdiff_t index = GetOpcodeArrayIndex(opcode); + if (index < 0 || index >= std::ptrdiff_t(NUM_CMSG_OPCODES)) { TC_LOG_ERROR("network", "Tried to set handler for an invalid opcode {}", opcode); return false; } - if ((*this)[opcode] != nullptr) + if (_internalTableClient[index] != nullptr) { - TC_LOG_ERROR("network", "Tried to override client handler of {} with {} (opcode {})", (*this)[opcode]->Name, name, opcode); + TC_LOG_ERROR("network", "Tried to override client handler of {} with {} (opcode {})", _internalTableClient[index]->Name, name, opcode); return false; } @@ -77,7 +78,7 @@ void OpcodeTable::ValidateAndSetClientOpcode(OpcodeClient opcode, char const* na if (!ValidateClientOpcode(opcode, name)) return; - _internalTableClient[opcode - MIN_CMSG_OPCODE_NUMBER].reset(new ClientOpcodeHandler{ + _internalTableClient[GetOpcodeArrayIndex(opcode)].reset(new ClientOpcodeHandler{ .Name = name, .Status = status, .Call = call, @@ -93,7 +94,8 @@ bool OpcodeTable::ValidateServerOpcode(OpcodeServer opcode, char const* name, Co return false; } - if (opcode < MIN_SMSG_OPCODE_NUMBER || opcode > MAX_SMSG_OPCODE_NUMBER) + std::ptrdiff_t index = GetOpcodeArrayIndex(opcode); + if (index < 0 || index >= std::ptrdiff_t(NUM_SMSG_OPCODES)) { TC_LOG_ERROR("network", "Tried to set handler for an invalid opcode {}", opcode); return false; @@ -111,9 +113,9 @@ bool OpcodeTable::ValidateServerOpcode(OpcodeServer opcode, char const* name, Co return false; } - if ((*this)[opcode] != nullptr) + if (_internalTableServer[index] != nullptr) { - TC_LOG_ERROR("network", "Tried to override server handler of {} with {} (opcode {})", (*this)[opcode]->Name, name, opcode); + TC_LOG_ERROR("network", "Tried to override server handler of {} with {} (opcode {})", _internalTableServer[index]->Name, name, opcode); return false; } @@ -125,7 +127,7 @@ void OpcodeTable::ValidateAndSetServerOpcode(OpcodeServer opcode, char const* na if (!ValidateServerOpcode(opcode, name, conIdx)) return; - _internalTableServer[opcode - MIN_SMSG_OPCODE_NUMBER].reset(new ServerOpcodeHandler{ .Name = name, .Status = status, .ConnectionIndex = conIdx }); + _internalTableServer[GetOpcodeArrayIndex(opcode)].reset(new ServerOpcodeHandler{ .Name = name, .Status = status, .ConnectionIndex = conIdx }); } /// Correspondence between opcodes and their names @@ -1943,15 +1945,16 @@ void OpcodeTable::InitializeServerOpcodes() #undef DEFINE_SERVER_OPCODE_HANDLER } -template<std::size_t MIN_OPCODE, std::size_t MAX_OPCODE, typename T> -inline std::string GetOpcodeNameForLoggingImpl(T id) +template<typename OpcodeDefinition, std::size_t N, typename T> +inline std::string GetOpcodeNameForLoggingImpl(std::array<OpcodeDefinition, N> const& definitions, T id) { uint32 opcode = uint32(id); char const* name = nullptr; - if (opcode >= MIN_OPCODE && opcode <= MAX_OPCODE) + std::ptrdiff_t index = GetOpcodeArrayIndex(id); + if (index >= 0 && index < std::ssize(definitions)) { - if (auto const* handler = opcodeTable[id]) + if (auto const* handler = definitions[index].get()) name = handler->Name; else name = "UNKNOWN OPCODE"; @@ -1959,15 +1962,15 @@ inline std::string GetOpcodeNameForLoggingImpl(T id) else name = "INVALID OPCODE"; - return Trinity::StringFormat("[{0} 0x{1:04X} ({1})]", name, opcode); + return Trinity::StringFormat("[{0} 0x{1:06X} ({1})]", name, opcode); } std::string GetOpcodeNameForLogging(OpcodeClient opcode) { - return GetOpcodeNameForLoggingImpl<MIN_CMSG_OPCODE_NUMBER, MAX_CMSG_OPCODE_NUMBER>(opcode); + return GetOpcodeNameForLoggingImpl(opcodeTable._internalTableClient, opcode); } std::string GetOpcodeNameForLogging(OpcodeServer opcode) { - return GetOpcodeNameForLoggingImpl<MIN_SMSG_OPCODE_NUMBER, MAX_SMSG_OPCODE_NUMBER>(opcode); + return GetOpcodeNameForLoggingImpl(opcodeTable._internalTableServer, opcode); } diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 9e041978c99..2666c3682b5 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -36,17 +36,9 @@ enum ConnectionType : int8 CONNECTION_TYPE_DEFAULT = -1 }; -constexpr std::size_t MIN_CMSG_OPCODE_NUMBER = 0x3126; -constexpr std::size_t MAX_CMSG_OPCODE_NUMBER = 0x5034; -constexpr std::size_t NUM_CMSG_OPCODES = MAX_CMSG_OPCODE_NUMBER - MIN_CMSG_OPCODE_NUMBER + 1; - -constexpr std::size_t MIN_SMSG_OPCODE_NUMBER = 0x256C; -constexpr std::size_t MAX_SMSG_OPCODE_NUMBER = 0x3052; -constexpr std::size_t NUM_SMSG_OPCODES = MAX_SMSG_OPCODE_NUMBER - MIN_SMSG_OPCODE_NUMBER + 1; - constexpr uint16 UNKNOWN_OPCODE = 0xBADD; // special marker value for uninitialized WorldPackets -enum OpcodeClient : uint16 +enum OpcodeClient : uint32 { CMSG_ACCEPT_GUILD_INVITE = 0x35FD, CMSG_ACCEPT_SOCIAL_CONTRACT = 0x374B, @@ -735,6 +727,27 @@ enum OpcodeClient : uint16 CMSG_WRAP_ITEM = 0x3994, }; +inline constexpr std::size_t NUM_CMSG_OPCODES = 1699; + +inline constexpr std::ptrdiff_t GetOpcodeArrayIndex(OpcodeClient opcode) +{ + uint32 idInGroup = opcode & 0xFFFF; + switch (opcode >> 16) + { + case 0x2A: return idInGroup < 26 ? idInGroup + 0 : -1; + case 0x2C: return idInGroup < 47 ? idInGroup + 26 : -1; + case 0x2D: return idInGroup < 3 ? idInGroup + 73 : -1; + case 0x2E: return idInGroup < 33 ? idInGroup + 76 : -1; + case 0x30: return idInGroup < 739 ? idInGroup + 109 : -1; + case 0x31: return idInGroup < 298 ? idInGroup + 848 : -1; + case 0x32: return idInGroup < 12 ? idInGroup + 1146 : -1; + case 0x33: return idInGroup < 130 ? idInGroup + 1158 : -1; + case 0x35: return idInGroup < 396 ? idInGroup + 1288 : -1; + case 0x36: return idInGroup < 15 ? idInGroup + 1684 : -1; + default: return -1; + } +} + enum OpcodeServer : uint16 { SMSG_ABORT_NEW_WORLD = 0x259C, @@ -1884,6 +1897,34 @@ enum OpcodeServer : uint16 SMSG_XP_AWARDED_FROM_CURRENCY = UNKNOWN_OPCODE, }; +inline constexpr std::size_t NUM_SMSG_OPCODES = 1445; + +inline constexpr std::ptrdiff_t GetOpcodeArrayIndex(OpcodeServer opcode) +{ + uint32 idInGroup = opcode & 0xFFFF; + switch (opcode >> 16) + { + case 0x37: return idInGroup < 831 ? idInGroup + 0 : -1; + case 0x38: return idInGroup < 10 ? idInGroup + 831 : -1; + case 0x3B: return idInGroup < 18 ? idInGroup + 841 : -1; + case 0x3C: return idInGroup < 33 ? idInGroup + 859 : -1; + case 0x3D: return idInGroup < 49 ? idInGroup + 892 : -1; + case 0x3E: return idInGroup < 11 ? idInGroup + 941 : -1; + case 0x3F: return idInGroup < 12 ? idInGroup + 952 : -1; + case 0x41: return idInGroup < 82 ? idInGroup + 964 : -1; + case 0x43: return idInGroup < 67 ? idInGroup + 1046 : -1; + case 0x45: return idInGroup < 32 ? idInGroup + 1113 : -1; + case 0x47: return idInGroup < 1 ? idInGroup + 1145 : -1; + case 0x48: return idInGroup < 118 ? idInGroup + 1146 : -1; + case 0x4A: return idInGroup < 46 ? idInGroup + 1264 : -1; + case 0x4B: return idInGroup < 41 ? idInGroup + 1310 : -1; + case 0x4D: return idInGroup < 85 ? idInGroup + 1351 : -1; + case 0x4E: return idInGroup < 8 ? idInGroup + 1436 : -1; + case 0x50: return idInGroup < 1 ? idInGroup + 1444 : -1; + default: return -1; + } +} + constexpr bool IsInstanceOnlyOpcode(uint32 opcode) { switch (opcode) @@ -1942,6 +1983,10 @@ struct ServerOpcodeHandler final ConnectionType ConnectionIndex; }; +/// Lookup opcode name for human understandable logging +std::string GetOpcodeNameForLogging(OpcodeClient opcode); +std::string GetOpcodeNameForLogging(OpcodeServer opcode); + class OpcodeTable { public: @@ -1950,14 +1995,26 @@ public: void Initialize(); + bool IsValid(OpcodeClient index) const + { + std::ptrdiff_t opcodeArrayIndex = GetOpcodeArrayIndex(index); + return opcodeArrayIndex >= 0 && opcodeArrayIndex < std::ssize(_internalTableClient); + } + + bool IsValid(OpcodeServer index) const + { + std::ptrdiff_t opcodeArrayIndex = GetOpcodeArrayIndex(index); + return opcodeArrayIndex >= 0 && opcodeArrayIndex < std::ssize(_internalTableServer); + } + ClientOpcodeHandler const* operator[](OpcodeClient index) const { - return _internalTableClient[index - MIN_CMSG_OPCODE_NUMBER].get(); + return _internalTableClient[GetOpcodeArrayIndex(index)].get(); } ServerOpcodeHandler const* operator[](OpcodeServer index) const { - return _internalTableServer[index - MIN_SMSG_OPCODE_NUMBER].get(); + return _internalTableServer[GetOpcodeArrayIndex(index)].get(); } private: @@ -1972,13 +2029,12 @@ private: std::array<std::unique_ptr<ClientOpcodeHandler>, NUM_CMSG_OPCODES> _internalTableClient; std::array<std::unique_ptr<ServerOpcodeHandler>, NUM_SMSG_OPCODES> _internalTableServer; + + friend std::string GetOpcodeNameForLogging(OpcodeClient opcode); + friend std::string GetOpcodeNameForLogging(OpcodeServer opcode); }; extern OpcodeTable opcodeTable; -/// Lookup opcode name for human understandable logging -std::string GetOpcodeNameForLogging(OpcodeClient opcode); -std::string GetOpcodeNameForLogging(OpcodeServer opcode); - #endif /// @} diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp index c912114849d..9c7c8a73f71 100644 --- a/src/server/game/Server/Protocol/PacketLog.cpp +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -137,7 +137,7 @@ void PacketLog::LogPacket(WorldPacket const& packet, Direction direction, boost: header.OptionalData.SocketPort = port; std::size_t size = packet.size(); if (direction == CLIENT_TO_SERVER) - size -= 2; + size -= 4; header.Length = size + sizeof(header.Opcode); header.Opcode = packet.GetOpcode(); @@ -147,7 +147,7 @@ void PacketLog::LogPacket(WorldPacket const& packet, Direction direction, boost: { uint8 const* data = packet.contents(); if (direction == CLIENT_TO_SERVER) - data += 2; + data += 4; fwrite(data, 1, size, _file); } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index f308f1833f0..dedb76379ed 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -212,7 +212,7 @@ std::string WorldSession::GetPlayerInfo() const /// Send a packet to the client void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/) { - if (packet->GetOpcode() < MIN_SMSG_OPCODE_NUMBER || packet->GetOpcode() > MAX_SMSG_OPCODE_NUMBER) + if (!opcodeTable.IsValid(static_cast<OpcodeServer>(packet->GetOpcode()))) { char const* specialName = packet->GetOpcode() == UNKNOWN_OPCODE ? "UNKNOWN_OPCODE" : "INVALID_OPCODE"; TC_LOG_ERROR("network.opcode", "Prevented sending of {} (0x{:04X}) to {}", specialName, packet->GetOpcode(), GetPlayerInfo()); @@ -1312,7 +1312,7 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co } } -uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) const +uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint32 opcode) const { uint32 maxPacketCounterAllowed; switch (opcode) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 27373327b9a..7a3ef59d131 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1740,13 +1740,13 @@ class TC_GAME_API WorldSession POLICY_BAN, }; - uint32 GetMaxPacketCounterAllowed(uint16 opcode) const; + uint32 GetMaxPacketCounterAllowed(uint32 opcode) const; WorldSession* Session; private: Policy _policy; - typedef std::unordered_map<uint16, PacketCounter> PacketThrottlingMap; + typedef std::unordered_map<uint32, PacketCounter> PacketThrottlingMap; // mark this member as "mutable" so it can be modified even in const functions mutable PacketThrottlingMap _PacketThrottlingMap; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index a34477b8100..4cf8ba07c94 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -329,7 +329,7 @@ bool WorldSocket::ReadHeaderHandler() ASSERT(_headerBuffer.GetActiveSize() == sizeof(IncomingPacketHeader), "Header size " SZFMTD " different than expected " SZFMTD, _headerBuffer.GetActiveSize(), sizeof(IncomingPacketHeader)); IncomingPacketHeader* header = reinterpret_cast<IncomingPacketHeader*>(_headerBuffer.GetReadPointer()); - uint16 encryptedOpcode = header->EncryptedOpcode; + uint32 encryptedOpcode = header->EncryptedOpcode; if (!header->IsValidSize()) { @@ -362,7 +362,7 @@ WorldSocket::ReadDataHandlerResult WorldSocket::ReadDataHandler() WorldPacket packet(std::move(_packetBuffer), GetConnectionType()); OpcodeClient opcode = packet.read<OpcodeClient>(); - if (opcode < MIN_CMSG_OPCODE_NUMBER || opcode > MAX_CMSG_OPCODE_NUMBER) + if (!opcodeTable.IsValid(opcode)) { TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client {} sent wrong opcode (opcode: {})", GetRemoteIpAddress().to_string(), uint32(opcode)); @@ -536,7 +536,7 @@ void WorldSocket::SendPacket(WorldPacket const& packet) void WorldSocket::WritePacketToBuffer(EncryptablePacket const& packet, MessageBuffer& buffer) { - uint16 opcode = packet.GetOpcode(); + uint32 opcode = packet.GetOpcode(); uint32 packetSize = packet.size(); // Reserve space for buffer @@ -548,8 +548,8 @@ void WorldSocket::WritePacketToBuffer(EncryptablePacket const& packet, MessageBu if (packetSize > MinSizeForCompression && packet.NeedsEncryption()) { CompressedWorldPacket cmp; - cmp.UncompressedSize = packetSize + 2; - cmp.UncompressedAdler = adler32(adler32(0x9827D8F1, (Bytef*)&opcode, 2), packet.contents(), packetSize); + cmp.UncompressedSize = packetSize + sizeof(opcode); + cmp.UncompressedAdler = adler32(adler32(0x9827D8F1, (Bytef*)&opcode, sizeof(opcode)), packet.contents(), packetSize); // Reserve space for compression info - uncompressed size and checksums uint8* compressionInfo = buffer.GetWritePointer(); @@ -569,7 +569,7 @@ void WorldSocket::WritePacketToBuffer(EncryptablePacket const& packet, MessageBu buffer.Write(packet.contents(), packet.size()); memcpy(dataPos, &opcode, sizeof(opcode)); - packetSize += 2 /*opcode*/; + packetSize += sizeof(opcode); PacketHeader header; header.Size = packetSize; @@ -581,12 +581,12 @@ void WorldSocket::WritePacketToBuffer(EncryptablePacket const& packet, MessageBu uint32 WorldSocket::CompressPacket(uint8* buffer, WorldPacket const& packet) { uint32 opcode = packet.GetOpcode(); - uint32 bufferSize = deflateBound(_compressionStream, packet.size() + sizeof(uint16)); + uint32 bufferSize = deflateBound(_compressionStream, packet.size() + sizeof(opcode)); _compressionStream->next_out = buffer; _compressionStream->avail_out = bufferSize; _compressionStream->next_in = (Bytef*)&opcode; - _compressionStream->avail_in = sizeof(uint16); + _compressionStream->avail_in = sizeof(opcode); int32 z_res = deflate(_compressionStream, Z_NO_FLUSH); if (z_res != Z_OK) diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 35f58161b53..03fb9d87542 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -40,7 +40,7 @@ class EncryptablePacket; class WorldPacket; class WorldSession; enum ConnectionType : int8; -enum OpcodeClient : uint16; +enum OpcodeClient : uint32; class EncryptablePacket : public WorldPacket { @@ -82,7 +82,7 @@ struct PacketHeader struct IncomingPacketHeader : PacketHeader { - uint16 EncryptedOpcode; + uint32 EncryptedOpcode; }; #pragma pack(pop) |