mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 09:33:51 +00:00
fix(chat): handle SMSG_GM_MESSAGECHAT format, add chat diagnostics
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
SMSG_GM_MESSAGECHAT has an extra gmNameLen+gmName field after the standard header that was causing misaligned parsing for non-whisper GM messages. Strip the GM name before forwarding to the regular parser. Also improve party state notifications (show member names on join) and add INFO-level logging for all incoming/outgoing chat messages and WARNING-level logging for group invite/accept packets to diagnose recurring phantom party state issues.
This commit is contained in:
parent
e4bd380c0d
commit
a23c2172a8
2 changed files with 40 additions and 6 deletions
|
|
@ -20,7 +20,31 @@ void ChatHandler::registerOpcodes(DispatchTable& table) {
|
|||
if (owner_.getState() == WorldState::IN_WORLD) handleMessageChat(packet);
|
||||
};
|
||||
table[Opcode::SMSG_GM_MESSAGECHAT] = [this](network::Packet& packet) {
|
||||
if (owner_.getState() == WorldState::IN_WORLD) handleMessageChat(packet);
|
||||
if (owner_.getState() != WorldState::IN_WORLD) return;
|
||||
// SMSG_GM_MESSAGECHAT has the same header as SMSG_MESSAGECHAT
|
||||
// (type[1]+lang[4]+senderGuid[8]+unk[4] = 17 bytes) followed by an
|
||||
// extra gmNameLen[4]+gmName[N] before the type-specific body.
|
||||
// Strip the GM name field to produce standard SMSG_MESSAGECHAT format.
|
||||
if (!packet.hasRemaining(21)) return; // 17 header + 4 gmNameLen min
|
||||
uint8_t type = packet.readUInt8();
|
||||
uint32_t lang = packet.readUInt32();
|
||||
uint64_t senderGuid = packet.readUInt64();
|
||||
uint32_t unk = packet.readUInt32();
|
||||
uint32_t gmNameLen = packet.readUInt32();
|
||||
if (!packet.hasRemaining(gmNameLen)) return;
|
||||
packet.setReadPos(packet.getReadPos() + gmNameLen); // skip gmName
|
||||
|
||||
// Rebuild as regular SMSG_MESSAGECHAT (header + remaining body)
|
||||
network::Packet regular(0);
|
||||
regular.writeUInt8(type);
|
||||
regular.writeUInt32(lang);
|
||||
regular.writeUInt64(senderGuid);
|
||||
regular.writeUInt32(unk);
|
||||
const auto& raw = packet.getData();
|
||||
size_t pos = packet.getReadPos();
|
||||
if (pos < raw.size())
|
||||
regular.writeBytes(raw.data() + pos, raw.size() - pos);
|
||||
handleMessageChat(regular);
|
||||
};
|
||||
table[Opcode::SMSG_TEXT_EMOTE] = [this](network::Packet& packet) {
|
||||
if (owner_.getState() == WorldState::IN_WORLD) handleTextEmote(packet);
|
||||
|
|
@ -120,7 +144,8 @@ void ChatHandler::sendChatMessage(ChatType type, const std::string& message, con
|
|||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("OUTGOING CHAT: type=", static_cast<int>(type), " msg='", message.substr(0, 60), "'");
|
||||
LOG_INFO("OUTGOING CHAT: type=", static_cast<int>(type),
|
||||
" (", getChatTypeString(type), ") target='", target, "' msg='", message.substr(0, 60), "'");
|
||||
|
||||
// Use the player's faction language. AzerothCore rejects wrong language.
|
||||
// Alliance races: Human(1), Dwarf(3), NightElf(4), Gnome(7), Draenei(11) → COMMON (7)
|
||||
|
|
@ -165,9 +190,9 @@ void ChatHandler::handleMessageChat(network::Packet& packet) {
|
|||
LOG_WARNING("Failed to parse SMSG_MESSAGECHAT, size=", packet.getSize());
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("SMSG_MESSAGECHAT: type=", static_cast<int>(data.type),
|
||||
" sender='", data.senderName, "' msg='",
|
||||
data.message.substr(0, 60), "'");
|
||||
LOG_INFO("INCOMING CHAT: type=", static_cast<int>(data.type),
|
||||
" (", getChatTypeString(data.type), ") sender=0x", std::hex, data.senderGuid, std::dec,
|
||||
" '", data.senderName, "' msg='", data.message.substr(0, 60), "'");
|
||||
|
||||
// Skip server echo of our own messages (we already added a local echo)
|
||||
if (data.senderGuid == owner_.playerGuid && data.senderGuid != 0) {
|
||||
|
|
|
|||
|
|
@ -1087,12 +1087,14 @@ void SocialHandler::handleDuelWinner(network::Packet& packet) {
|
|||
|
||||
void SocialHandler::inviteToGroup(const std::string& playerName) {
|
||||
if (owner_.getState() != WorldState::IN_WORLD || !owner_.socket) return;
|
||||
LOG_WARNING(">>> Sending CMSG_GROUP_INVITE to '", playerName, "'");
|
||||
auto packet = GroupInvitePacket::build(playerName);
|
||||
owner_.socket->send(packet);
|
||||
}
|
||||
|
||||
void SocialHandler::acceptGroupInvite() {
|
||||
if (owner_.getState() != WorldState::IN_WORLD || !owner_.socket) return;
|
||||
LOG_WARNING(">>> Sending CMSG_GROUP_ACCEPT");
|
||||
pendingGroupInvite = false;
|
||||
auto packet = GroupAcceptPacket::build();
|
||||
owner_.socket->send(packet);
|
||||
|
|
@ -1244,8 +1246,15 @@ void SocialHandler::handleGroupList(network::Packet& packet) {
|
|||
const bool nowInGroup = !partyData.isEmpty();
|
||||
if (!nowInGroup && wasInGroup) {
|
||||
owner_.addSystemChatMessage("You are no longer in a group.");
|
||||
LOG_INFO("Left group");
|
||||
} else if (nowInGroup && !wasInGroup) {
|
||||
owner_.addSystemChatMessage("You are now in a group.");
|
||||
std::string members;
|
||||
for (const auto& m : partyData.members) {
|
||||
if (!members.empty()) members += ", ";
|
||||
members += m.name.empty() ? "?" : m.name;
|
||||
}
|
||||
owner_.addSystemChatMessage("You joined a group with: " + members);
|
||||
LOG_INFO("Joined group with ", partyData.memberCount, " members: ", members);
|
||||
}
|
||||
// Loot method change notification
|
||||
if (wasInGroup && nowInGroup && partyData.lootMethod != prevLootMethod) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue