Fix talent system packet parsing and rank logic

- Parse SMSG_TALENTS_INFO with correct byte-for-byte structure:
  * Header: uint8 spec, uint8 unspent, be32 talentCount, be16 entryCount
  * Entries: entryCount × (le32 id + uint8 rank)
  * Glyphs: uint8 glyphSlots + glyphSlots × le16 glyphId
- Fix rank storage: store all talents from packet (rank 0 = first point)
- Fix UI rank logic: send rank 0 for new, rank+1 for upgrades
- Fix rank display: show (rank+1) for learned talents
- Add sanity checks: entryCount max 64, glyphSlots max 12
- Add network boundary logging for packet debugging
This commit is contained in:
Kelsi 2026-02-10 13:16:38 -08:00
parent e7556605d7
commit 3c13cf4b12
5 changed files with 141 additions and 31 deletions

View file

@ -3,6 +3,8 @@
#include "network/net_platform.hpp"
#include "auth/crypto.hpp"
#include "core/logger.hpp"
#include <iomanip>
#include <sstream>
namespace wowee {
namespace network {
@ -259,6 +261,29 @@ void WorldSocket::tryParsePackets() {
// Create packet with opcode and payload
Packet packet(opcode, packetData);
// Log raw SMSG_TALENTS_INFO packets at network boundary
if (opcode == 0x4C0) { // SMSG_TALENTS_INFO
std::stringstream headerHex, payloadHex;
headerHex << std::hex << std::setfill('0');
payloadHex << std::hex << std::setfill('0');
// Header (4 bytes from receiveBuffer before packetData extraction)
// Note: receiveBuffer still has the full packet at this point
for (size_t i = 0; i < 4 && i < receiveBuffer.size(); ++i) {
headerHex << std::setw(2) << (int)(uint8_t)receiveBuffer[i] << " ";
}
// Payload (ALL bytes)
for (size_t i = 0; i < packetData.size(); ++i) {
payloadHex << std::setw(2) << (int)(uint8_t)packetData[i] << " ";
}
LOG_INFO("=== SMSG_TALENTS_INFO RAW PACKET ===");
LOG_INFO("Header: ", headerHex.str());
LOG_INFO("Payload: ", payloadHex.str());
LOG_INFO("Total payload size: ", packetData.size(), " bytes");
}
// Remove parsed data from buffer and reset header decryption counter
receiveBuffer.erase(receiveBuffer.begin(), receiveBuffer.begin() + totalSize);
headerBytesDecrypted = 0;