From fed03f970cd6ba83653e6a72865a424414b3454c Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 11 Mar 2026 04:22:18 -0700 Subject: [PATCH] fix: correct SMSG_BATTLEFIELD_STATUS Classic 1.12 packet layout Classic uses queueSlot(4)+bgTypeId(4)+unk(2)+instanceId(4)+isReg(1)+statusId(4); TBC/WotLK prefixes arenaType(1)+unk(1) before bgTypeId. Reading TBC format on Classic caused bgTypeId to be read from wrong offset, corrupting BG queue state. --- src/game/game_handler.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 06e4c057..18b5a54f 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -12242,20 +12242,40 @@ void GameHandler::handleMoveKnockBack(network::Packet& packet) { // ============================================================ void GameHandler::handleBattlefieldStatus(network::Packet& packet) { + // SMSG_BATTLEFIELD_STATUS wire format differs by expansion: + // + // Classic 1.12 (vmangos/cmangos): + // queueSlot(4) bgTypeId(4) unk(2) instanceId(4) isRegistered(1) statusId(4) [status fields...] + // STATUS_NONE sends only: queueSlot(4) bgTypeId(4) + // + // TBC 2.4.3 / WotLK 3.3.5a: + // queueSlot(4) arenaType(1) unk(1) bgTypeId(4) unk2(2) instanceId(4) isRated(1) statusId(4) [status fields...] + // STATUS_NONE sends only: queueSlot(4) arenaType(1) + if (packet.getSize() - packet.getReadPos() < 4) return; uint32_t queueSlot = packet.readUInt32(); - // Minimal packet = just queueSlot + arenaType(1) when status is NONE - if (packet.getSize() - packet.getReadPos() < 1) { - LOG_INFO("Battlefield status: queue slot ", queueSlot, " cleared"); - return; + const bool classicFormat = isClassicLikeExpansion(); + + uint8_t arenaType = 0; + if (!classicFormat) { + // TBC/WotLK: arenaType(1) + unk(1) before bgTypeId + // STATUS_NONE sends only queueSlot + arenaType + if (packet.getSize() - packet.getReadPos() < 1) { + LOG_INFO("Battlefield status: queue slot ", queueSlot, " cleared"); + return; + } + arenaType = packet.readUInt8(); + if (packet.getSize() - packet.getReadPos() < 1) return; + packet.readUInt8(); // unk + } else { + // Classic STATUS_NONE sends only queueSlot + bgTypeId (4 bytes) + if (packet.getSize() - packet.getReadPos() < 4) { + LOG_INFO("Battlefield status: queue slot ", queueSlot, " cleared"); + return; + } } - uint8_t arenaType = packet.readUInt8(); - if (packet.getSize() - packet.getReadPos() < 1) return; - - // Unknown byte - packet.readUInt8(); if (packet.getSize() - packet.getReadPos() < 4) return; uint32_t bgTypeId = packet.readUInt32();