diff --git a/Data/expansions/turtle/opcodes.json b/Data/expansions/turtle/opcodes.json index da0efa4e..369ace2e 100644 --- a/Data/expansions/turtle/opcodes.json +++ b/Data/expansions/turtle/opcodes.json @@ -37,6 +37,7 @@ "SMSG_ACCOUNT_DATA_TIMES": "0x209", "SMSG_UPDATE_OBJECT": "0x0A9", "SMSG_COMPRESSED_UPDATE_OBJECT": "0x1F6", + "SMSG_UNKNOWN_1F5": "0x1F5", "SMSG_MONSTER_MOVE_TRANSPORT": "0x2AE", "SMSG_SPLINE_MOVE_SET_WALK_MODE": "0x30D", "SMSG_SPLINE_MOVE_SET_RUN_MODE": "0x30E", @@ -284,5 +285,6 @@ "SMSG_AUCTION_OWNER_NOTIFICATION": "0x25E", "SMSG_AUCTION_BIDDER_NOTIFICATION": "0x260", "CMSG_AUCTION_LIST_BIDDER_ITEMS": "0x264", - "SMSG_AUCTION_BIDDER_LIST_RESULT": "0x265" + "SMSG_AUCTION_BIDDER_LIST_RESULT": "0x265", + "SMSG_UNKNOWN_319": "0x319" } diff --git a/include/game/opcode_table.hpp b/include/game/opcode_table.hpp index ab953e46..7b11516b 100644 --- a/include/game/opcode_table.hpp +++ b/include/game/opcode_table.hpp @@ -64,6 +64,7 @@ enum class LogicalOpcode : uint16_t { // ---- Entity/Object updates ---- SMSG_UPDATE_OBJECT, SMSG_COMPRESSED_UPDATE_OBJECT, + SMSG_UNKNOWN_1F5, SMSG_MONSTER_MOVE_TRANSPORT, SMSG_SPLINE_MOVE_SET_WALK_MODE, SMSG_SPLINE_MOVE_SET_RUN_MODE, @@ -440,6 +441,9 @@ enum class LogicalOpcode : uint16_t { SMSG_AUCTION_BIDDER_NOTIFICATION, CMSG_AUCTION_LIST_BIDDER_ITEMS, + // ---- Expansion-Specific / Unknown (safe consume) ---- + SMSG_UNKNOWN_319, + // Sentinel COUNT }; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index b54efd0f..f4d3adc1 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -914,6 +914,10 @@ void GameHandler::handlePacket(network::Packet& packet) { handleCompressedUpdateObject(packet); } break; + case Opcode::SMSG_UNKNOWN_1F5: + // Observed custom server packet (16 bytes). Consume safely for stream alignment. + packet.setReadPos(packet.getSize()); + break; case Opcode::SMSG_DESTROY_OBJECT: // Can be received after entering world @@ -1000,6 +1004,11 @@ void GameHandler::handlePacket(network::Packet& packet) { handleRandomRoll(packet); } break; + case Opcode::CMSG_DUEL_PROPOSED: + // Some servers reuse this wire value for an outbound server packet variant. + // Consume safely until we have a concrete parser. + packet.setReadPos(packet.getSize()); + break; case Opcode::SMSG_LOGOUT_RESPONSE: handleLogoutResponse(packet); @@ -2032,6 +2041,10 @@ void GameHandler::handlePacket(network::Packet& packet) { case Opcode::SMSG_AUCTION_COMMAND_RESULT: handleAuctionCommandResult(packet); break; + case Opcode::SMSG_UNKNOWN_319: + // Observed custom server packet (8 bytes). Safe-consume for now. + packet.setReadPos(packet.getSize()); + break; default: // In pre-world states we need full visibility (char create/login handshakes). diff --git a/src/game/opcode_table.cpp b/src/game/opcode_table.cpp index a7024d12..8e1208d7 100644 --- a/src/game/opcode_table.cpp +++ b/src/game/opcode_table.cpp @@ -63,6 +63,7 @@ static const OpcodeNameEntry kOpcodeNames[] = { {"SMSG_MOTD", LogicalOpcode::SMSG_MOTD}, {"SMSG_UPDATE_OBJECT", LogicalOpcode::SMSG_UPDATE_OBJECT}, {"SMSG_COMPRESSED_UPDATE_OBJECT", LogicalOpcode::SMSG_COMPRESSED_UPDATE_OBJECT}, + {"SMSG_UNKNOWN_1F5", LogicalOpcode::SMSG_UNKNOWN_1F5}, {"SMSG_MONSTER_MOVE_TRANSPORT", LogicalOpcode::SMSG_MONSTER_MOVE_TRANSPORT}, {"SMSG_SPLINE_MOVE_SET_WALK_MODE", LogicalOpcode::SMSG_SPLINE_MOVE_SET_WALK_MODE}, {"SMSG_SPLINE_MOVE_SET_RUN_MODE", LogicalOpcode::SMSG_SPLINE_MOVE_SET_RUN_MODE}, @@ -360,6 +361,7 @@ static const OpcodeNameEntry kOpcodeNames[] = { {"SMSG_AUCTION_OWNER_NOTIFICATION", LogicalOpcode::SMSG_AUCTION_OWNER_NOTIFICATION}, {"SMSG_AUCTION_BIDDER_NOTIFICATION", LogicalOpcode::SMSG_AUCTION_BIDDER_NOTIFICATION}, {"CMSG_AUCTION_LIST_BIDDER_ITEMS", LogicalOpcode::CMSG_AUCTION_LIST_BIDDER_ITEMS}, + {"SMSG_UNKNOWN_319", LogicalOpcode::SMSG_UNKNOWN_319}, }; // clang-format on