2026-02-12 22:56:36 -08:00
|
|
|
#include "game/opcode_table.hpp"
|
|
|
|
|
#include "core/logger.hpp"
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cctype>
|
|
|
|
|
|
|
|
|
|
namespace wowee {
|
|
|
|
|
namespace game {
|
|
|
|
|
|
|
|
|
|
// Global active opcode table pointer
|
|
|
|
|
static const OpcodeTable* g_activeOpcodeTable = nullptr;
|
|
|
|
|
|
|
|
|
|
void setActiveOpcodeTable(const OpcodeTable* table) { g_activeOpcodeTable = table; }
|
|
|
|
|
const OpcodeTable* getActiveOpcodeTable() { return g_activeOpcodeTable; }
|
|
|
|
|
|
|
|
|
|
// Name ↔ LogicalOpcode mapping table (generated from the enum)
|
|
|
|
|
struct OpcodeNameEntry {
|
|
|
|
|
const char* name;
|
|
|
|
|
LogicalOpcode op;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
static const OpcodeNameEntry kOpcodeNames[] = {
|
|
|
|
|
{"CMSG_PING", LogicalOpcode::CMSG_PING},
|
|
|
|
|
{"CMSG_AUTH_SESSION", LogicalOpcode::CMSG_AUTH_SESSION},
|
|
|
|
|
{"CMSG_CHAR_CREATE", LogicalOpcode::CMSG_CHAR_CREATE},
|
|
|
|
|
{"CMSG_CHAR_ENUM", LogicalOpcode::CMSG_CHAR_ENUM},
|
|
|
|
|
{"CMSG_CHAR_DELETE", LogicalOpcode::CMSG_CHAR_DELETE},
|
|
|
|
|
{"CMSG_PLAYER_LOGIN", LogicalOpcode::CMSG_PLAYER_LOGIN},
|
|
|
|
|
{"CMSG_MOVE_START_FORWARD", LogicalOpcode::CMSG_MOVE_START_FORWARD},
|
|
|
|
|
{"CMSG_MOVE_START_BACKWARD", LogicalOpcode::CMSG_MOVE_START_BACKWARD},
|
|
|
|
|
{"CMSG_MOVE_STOP", LogicalOpcode::CMSG_MOVE_STOP},
|
|
|
|
|
{"CMSG_MOVE_START_STRAFE_LEFT", LogicalOpcode::CMSG_MOVE_START_STRAFE_LEFT},
|
|
|
|
|
{"CMSG_MOVE_START_STRAFE_RIGHT", LogicalOpcode::CMSG_MOVE_START_STRAFE_RIGHT},
|
|
|
|
|
{"CMSG_MOVE_STOP_STRAFE", LogicalOpcode::CMSG_MOVE_STOP_STRAFE},
|
|
|
|
|
{"CMSG_MOVE_JUMP", LogicalOpcode::CMSG_MOVE_JUMP},
|
|
|
|
|
{"CMSG_MOVE_START_TURN_LEFT", LogicalOpcode::CMSG_MOVE_START_TURN_LEFT},
|
|
|
|
|
{"CMSG_MOVE_START_TURN_RIGHT", LogicalOpcode::CMSG_MOVE_START_TURN_RIGHT},
|
|
|
|
|
{"CMSG_MOVE_STOP_TURN", LogicalOpcode::CMSG_MOVE_STOP_TURN},
|
|
|
|
|
{"CMSG_MOVE_SET_FACING", LogicalOpcode::CMSG_MOVE_SET_FACING},
|
|
|
|
|
{"CMSG_MOVE_FALL_LAND", LogicalOpcode::CMSG_MOVE_FALL_LAND},
|
|
|
|
|
{"CMSG_MOVE_START_SWIM", LogicalOpcode::CMSG_MOVE_START_SWIM},
|
|
|
|
|
{"CMSG_MOVE_STOP_SWIM", LogicalOpcode::CMSG_MOVE_STOP_SWIM},
|
|
|
|
|
{"CMSG_MOVE_HEARTBEAT", LogicalOpcode::CMSG_MOVE_HEARTBEAT},
|
|
|
|
|
{"SMSG_AUTH_CHALLENGE", LogicalOpcode::SMSG_AUTH_CHALLENGE},
|
|
|
|
|
{"SMSG_AUTH_RESPONSE", LogicalOpcode::SMSG_AUTH_RESPONSE},
|
|
|
|
|
{"SMSG_CHAR_CREATE", LogicalOpcode::SMSG_CHAR_CREATE},
|
|
|
|
|
{"SMSG_CHAR_ENUM", LogicalOpcode::SMSG_CHAR_ENUM},
|
|
|
|
|
{"SMSG_CHAR_DELETE", LogicalOpcode::SMSG_CHAR_DELETE},
|
2026-02-17 13:59:29 -08:00
|
|
|
{"SMSG_CHARACTER_LOGIN_FAILED", LogicalOpcode::SMSG_CHARACTER_LOGIN_FAILED},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_PONG", LogicalOpcode::SMSG_PONG},
|
|
|
|
|
{"SMSG_LOGIN_VERIFY_WORLD", LogicalOpcode::SMSG_LOGIN_VERIFY_WORLD},
|
2026-02-18 23:26:58 -08:00
|
|
|
{"SMSG_INIT_WORLD_STATES", LogicalOpcode::SMSG_INIT_WORLD_STATES},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_LOGIN_SETTIMESPEED", LogicalOpcode::SMSG_LOGIN_SETTIMESPEED},
|
|
|
|
|
{"SMSG_TUTORIAL_FLAGS", LogicalOpcode::SMSG_TUTORIAL_FLAGS},
|
2026-02-18 23:26:58 -08:00
|
|
|
{"SMSG_INITIALIZE_FACTIONS", LogicalOpcode::SMSG_INITIALIZE_FACTIONS},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_WARDEN_DATA", LogicalOpcode::SMSG_WARDEN_DATA},
|
|
|
|
|
{"CMSG_WARDEN_DATA", LogicalOpcode::CMSG_WARDEN_DATA},
|
|
|
|
|
{"SMSG_ACCOUNT_DATA_TIMES", LogicalOpcode::SMSG_ACCOUNT_DATA_TIMES},
|
|
|
|
|
{"SMSG_CLIENTCACHE_VERSION", LogicalOpcode::SMSG_CLIENTCACHE_VERSION},
|
|
|
|
|
{"SMSG_FEATURE_SYSTEM_STATUS", LogicalOpcode::SMSG_FEATURE_SYSTEM_STATUS},
|
|
|
|
|
{"SMSG_MOTD", LogicalOpcode::SMSG_MOTD},
|
2026-02-20 00:28:51 -08:00
|
|
|
{"SMSG_NOTIFICATION", LogicalOpcode::SMSG_NOTIFICATION},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_UPDATE_OBJECT", LogicalOpcode::SMSG_UPDATE_OBJECT},
|
|
|
|
|
{"SMSG_COMPRESSED_UPDATE_OBJECT", LogicalOpcode::SMSG_COMPRESSED_UPDATE_OBJECT},
|
|
|
|
|
{"SMSG_MONSTER_MOVE_TRANSPORT", LogicalOpcode::SMSG_MONSTER_MOVE_TRANSPORT},
|
2026-02-18 23:38:34 -08:00
|
|
|
{"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},
|
|
|
|
|
{"SMSG_SPLINE_MOVE_SET_RUN_SPEED", LogicalOpcode::SMSG_SPLINE_MOVE_SET_RUN_SPEED},
|
|
|
|
|
{"SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED", LogicalOpcode::SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED},
|
|
|
|
|
{"SMSG_SPLINE_MOVE_SET_SWIM_SPEED", LogicalOpcode::SMSG_SPLINE_MOVE_SET_SWIM_SPEED},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_DESTROY_OBJECT", LogicalOpcode::SMSG_DESTROY_OBJECT},
|
|
|
|
|
{"CMSG_MESSAGECHAT", LogicalOpcode::CMSG_MESSAGECHAT},
|
|
|
|
|
{"SMSG_MESSAGECHAT", LogicalOpcode::SMSG_MESSAGECHAT},
|
|
|
|
|
{"CMSG_WHO", LogicalOpcode::CMSG_WHO},
|
|
|
|
|
{"SMSG_WHO", LogicalOpcode::SMSG_WHO},
|
|
|
|
|
{"CMSG_REQUEST_PLAYED_TIME", LogicalOpcode::CMSG_REQUEST_PLAYED_TIME},
|
|
|
|
|
{"SMSG_PLAYED_TIME", LogicalOpcode::SMSG_PLAYED_TIME},
|
|
|
|
|
{"CMSG_QUERY_TIME", LogicalOpcode::CMSG_QUERY_TIME},
|
|
|
|
|
{"SMSG_QUERY_TIME_RESPONSE", LogicalOpcode::SMSG_QUERY_TIME_RESPONSE},
|
|
|
|
|
{"SMSG_FRIEND_STATUS", LogicalOpcode::SMSG_FRIEND_STATUS},
|
2026-02-18 23:26:58 -08:00
|
|
|
{"SMSG_CONTACT_LIST", LogicalOpcode::SMSG_CONTACT_LIST},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_ADD_FRIEND", LogicalOpcode::CMSG_ADD_FRIEND},
|
|
|
|
|
{"CMSG_DEL_FRIEND", LogicalOpcode::CMSG_DEL_FRIEND},
|
|
|
|
|
{"CMSG_SET_CONTACT_NOTES", LogicalOpcode::CMSG_SET_CONTACT_NOTES},
|
|
|
|
|
{"CMSG_ADD_IGNORE", LogicalOpcode::CMSG_ADD_IGNORE},
|
|
|
|
|
{"CMSG_DEL_IGNORE", LogicalOpcode::CMSG_DEL_IGNORE},
|
|
|
|
|
{"CMSG_PLAYER_LOGOUT", LogicalOpcode::CMSG_PLAYER_LOGOUT},
|
|
|
|
|
{"CMSG_LOGOUT_REQUEST", LogicalOpcode::CMSG_LOGOUT_REQUEST},
|
|
|
|
|
{"CMSG_LOGOUT_CANCEL", LogicalOpcode::CMSG_LOGOUT_CANCEL},
|
|
|
|
|
{"SMSG_LOGOUT_RESPONSE", LogicalOpcode::SMSG_LOGOUT_RESPONSE},
|
|
|
|
|
{"SMSG_LOGOUT_COMPLETE", LogicalOpcode::SMSG_LOGOUT_COMPLETE},
|
|
|
|
|
{"CMSG_STAND_STATE_CHANGE", LogicalOpcode::CMSG_STAND_STATE_CHANGE},
|
|
|
|
|
{"CMSG_SHOWING_HELM", LogicalOpcode::CMSG_SHOWING_HELM},
|
|
|
|
|
{"CMSG_SHOWING_CLOAK", LogicalOpcode::CMSG_SHOWING_CLOAK},
|
|
|
|
|
{"CMSG_TOGGLE_PVP", LogicalOpcode::CMSG_TOGGLE_PVP},
|
|
|
|
|
{"CMSG_GUILD_INVITE", LogicalOpcode::CMSG_GUILD_INVITE},
|
|
|
|
|
{"CMSG_GUILD_ACCEPT", LogicalOpcode::CMSG_GUILD_ACCEPT},
|
|
|
|
|
{"CMSG_GUILD_DECLINE_INVITATION", LogicalOpcode::CMSG_GUILD_DECLINE_INVITATION},
|
|
|
|
|
{"CMSG_GUILD_INFO", LogicalOpcode::CMSG_GUILD_INFO},
|
|
|
|
|
{"CMSG_GUILD_GET_ROSTER", LogicalOpcode::CMSG_GUILD_GET_ROSTER},
|
|
|
|
|
{"CMSG_GUILD_PROMOTE_MEMBER", LogicalOpcode::CMSG_GUILD_PROMOTE_MEMBER},
|
|
|
|
|
{"CMSG_GUILD_DEMOTE_MEMBER", LogicalOpcode::CMSG_GUILD_DEMOTE_MEMBER},
|
|
|
|
|
{"CMSG_GUILD_LEAVE", LogicalOpcode::CMSG_GUILD_LEAVE},
|
|
|
|
|
{"CMSG_GUILD_MOTD", LogicalOpcode::CMSG_GUILD_MOTD},
|
|
|
|
|
{"SMSG_GUILD_INFO", LogicalOpcode::SMSG_GUILD_INFO},
|
|
|
|
|
{"SMSG_GUILD_ROSTER", LogicalOpcode::SMSG_GUILD_ROSTER},
|
2026-02-13 19:17:24 -08:00
|
|
|
{"CMSG_GUILD_QUERY", LogicalOpcode::CMSG_GUILD_QUERY},
|
|
|
|
|
{"SMSG_GUILD_QUERY_RESPONSE", LogicalOpcode::SMSG_GUILD_QUERY_RESPONSE},
|
|
|
|
|
{"SMSG_GUILD_INVITE", LogicalOpcode::SMSG_GUILD_INVITE},
|
|
|
|
|
{"CMSG_GUILD_REMOVE", LogicalOpcode::CMSG_GUILD_REMOVE},
|
2026-02-16 20:16:14 -08:00
|
|
|
{"CMSG_GUILD_DISBAND", LogicalOpcode::CMSG_GUILD_DISBAND},
|
|
|
|
|
{"CMSG_GUILD_LEADER", LogicalOpcode::CMSG_GUILD_LEADER},
|
|
|
|
|
{"CMSG_GUILD_SET_PUBLIC_NOTE", LogicalOpcode::CMSG_GUILD_SET_PUBLIC_NOTE},
|
|
|
|
|
{"CMSG_GUILD_SET_OFFICER_NOTE", LogicalOpcode::CMSG_GUILD_SET_OFFICER_NOTE},
|
2026-02-13 19:17:24 -08:00
|
|
|
{"SMSG_GUILD_EVENT", LogicalOpcode::SMSG_GUILD_EVENT},
|
|
|
|
|
{"SMSG_GUILD_COMMAND_RESULT", LogicalOpcode::SMSG_GUILD_COMMAND_RESULT},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"MSG_RAID_READY_CHECK", LogicalOpcode::MSG_RAID_READY_CHECK},
|
|
|
|
|
{"MSG_RAID_READY_CHECK_CONFIRM", LogicalOpcode::MSG_RAID_READY_CHECK_CONFIRM},
|
2026-02-20 01:13:01 -08:00
|
|
|
{"SMSG_ITEM_PUSH_RESULT", LogicalOpcode::SMSG_ITEM_PUSH_RESULT},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_DUEL_ACCEPTED", LogicalOpcode::CMSG_DUEL_ACCEPTED},
|
|
|
|
|
{"CMSG_DUEL_CANCELLED", LogicalOpcode::CMSG_DUEL_CANCELLED},
|
|
|
|
|
{"SMSG_DUEL_REQUESTED", LogicalOpcode::SMSG_DUEL_REQUESTED},
|
|
|
|
|
{"CMSG_INITIATE_TRADE", LogicalOpcode::CMSG_INITIATE_TRADE},
|
|
|
|
|
{"MSG_RANDOM_ROLL", LogicalOpcode::MSG_RANDOM_ROLL},
|
|
|
|
|
{"CMSG_SET_SELECTION", LogicalOpcode::CMSG_SET_SELECTION},
|
|
|
|
|
{"CMSG_NAME_QUERY", LogicalOpcode::CMSG_NAME_QUERY},
|
|
|
|
|
{"SMSG_NAME_QUERY_RESPONSE", LogicalOpcode::SMSG_NAME_QUERY_RESPONSE},
|
|
|
|
|
{"CMSG_CREATURE_QUERY", LogicalOpcode::CMSG_CREATURE_QUERY},
|
|
|
|
|
{"SMSG_CREATURE_QUERY_RESPONSE", LogicalOpcode::SMSG_CREATURE_QUERY_RESPONSE},
|
|
|
|
|
{"CMSG_GAMEOBJECT_QUERY", LogicalOpcode::CMSG_GAMEOBJECT_QUERY},
|
|
|
|
|
{"SMSG_GAMEOBJECT_QUERY_RESPONSE", LogicalOpcode::SMSG_GAMEOBJECT_QUERY_RESPONSE},
|
|
|
|
|
{"CMSG_SET_ACTIVE_MOVER", LogicalOpcode::CMSG_SET_ACTIVE_MOVER},
|
|
|
|
|
{"CMSG_BINDER_ACTIVATE", LogicalOpcode::CMSG_BINDER_ACTIVATE},
|
|
|
|
|
{"SMSG_LOG_XPGAIN", LogicalOpcode::SMSG_LOG_XPGAIN},
|
|
|
|
|
{"SMSG_MONSTER_MOVE", LogicalOpcode::SMSG_MONSTER_MOVE},
|
2026-02-18 03:15:25 -08:00
|
|
|
{"SMSG_COMPRESSED_MOVES", LogicalOpcode::SMSG_COMPRESSED_MOVES},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_ATTACKSWING", LogicalOpcode::CMSG_ATTACKSWING},
|
|
|
|
|
{"CMSG_ATTACKSTOP", LogicalOpcode::CMSG_ATTACKSTOP},
|
|
|
|
|
{"SMSG_ATTACKSTART", LogicalOpcode::SMSG_ATTACKSTART},
|
|
|
|
|
{"SMSG_ATTACKSTOP", LogicalOpcode::SMSG_ATTACKSTOP},
|
|
|
|
|
{"SMSG_ATTACKERSTATEUPDATE", LogicalOpcode::SMSG_ATTACKERSTATEUPDATE},
|
2026-02-18 23:38:34 -08:00
|
|
|
{"SMSG_AI_REACTION", LogicalOpcode::SMSG_AI_REACTION},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_SPELLNONMELEEDAMAGELOG", LogicalOpcode::SMSG_SPELLNONMELEEDAMAGELOG},
|
2026-02-18 23:38:34 -08:00
|
|
|
{"SMSG_PLAY_SPELL_VISUAL", LogicalOpcode::SMSG_PLAY_SPELL_VISUAL},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_SPELLHEALLOG", LogicalOpcode::SMSG_SPELLHEALLOG},
|
|
|
|
|
{"SMSG_SPELLENERGIZELOG", LogicalOpcode::SMSG_SPELLENERGIZELOG},
|
|
|
|
|
{"SMSG_PERIODICAURALOG", LogicalOpcode::SMSG_PERIODICAURALOG},
|
|
|
|
|
{"SMSG_ENVIRONMENTALDAMAGELOG", LogicalOpcode::SMSG_ENVIRONMENTALDAMAGELOG},
|
|
|
|
|
{"CMSG_CAST_SPELL", LogicalOpcode::CMSG_CAST_SPELL},
|
|
|
|
|
{"CMSG_CANCEL_CAST", LogicalOpcode::CMSG_CANCEL_CAST},
|
|
|
|
|
{"CMSG_CANCEL_AURA", LogicalOpcode::CMSG_CANCEL_AURA},
|
|
|
|
|
{"SMSG_CAST_FAILED", LogicalOpcode::SMSG_CAST_FAILED},
|
|
|
|
|
{"SMSG_SPELL_START", LogicalOpcode::SMSG_SPELL_START},
|
|
|
|
|
{"SMSG_SPELL_GO", LogicalOpcode::SMSG_SPELL_GO},
|
|
|
|
|
{"SMSG_SPELL_FAILURE", LogicalOpcode::SMSG_SPELL_FAILURE},
|
|
|
|
|
{"SMSG_SPELL_COOLDOWN", LogicalOpcode::SMSG_SPELL_COOLDOWN},
|
|
|
|
|
{"SMSG_COOLDOWN_EVENT", LogicalOpcode::SMSG_COOLDOWN_EVENT},
|
|
|
|
|
{"SMSG_UPDATE_AURA_DURATION", LogicalOpcode::SMSG_UPDATE_AURA_DURATION},
|
|
|
|
|
{"SMSG_INITIAL_SPELLS", LogicalOpcode::SMSG_INITIAL_SPELLS},
|
|
|
|
|
{"SMSG_LEARNED_SPELL", LogicalOpcode::SMSG_LEARNED_SPELL},
|
|
|
|
|
{"SMSG_SUPERCEDED_SPELL", LogicalOpcode::SMSG_SUPERCEDED_SPELL},
|
|
|
|
|
{"SMSG_REMOVED_SPELL", LogicalOpcode::SMSG_REMOVED_SPELL},
|
|
|
|
|
{"SMSG_SEND_UNLEARN_SPELLS", LogicalOpcode::SMSG_SEND_UNLEARN_SPELLS},
|
|
|
|
|
{"SMSG_SPELL_DELAYED", LogicalOpcode::SMSG_SPELL_DELAYED},
|
2026-02-17 15:57:51 -08:00
|
|
|
{"SMSG_CANCEL_AUTO_REPEAT", LogicalOpcode::SMSG_CANCEL_AUTO_REPEAT},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_AURA_UPDATE", LogicalOpcode::SMSG_AURA_UPDATE},
|
|
|
|
|
{"SMSG_AURA_UPDATE_ALL", LogicalOpcode::SMSG_AURA_UPDATE_ALL},
|
|
|
|
|
{"SMSG_SET_FLAT_SPELL_MODIFIER", LogicalOpcode::SMSG_SET_FLAT_SPELL_MODIFIER},
|
|
|
|
|
{"SMSG_SET_PCT_SPELL_MODIFIER", LogicalOpcode::SMSG_SET_PCT_SPELL_MODIFIER},
|
|
|
|
|
{"SMSG_TALENTS_INFO", LogicalOpcode::SMSG_TALENTS_INFO},
|
|
|
|
|
{"CMSG_LEARN_TALENT", LogicalOpcode::CMSG_LEARN_TALENT},
|
|
|
|
|
{"MSG_TALENT_WIPE_CONFIRM", LogicalOpcode::MSG_TALENT_WIPE_CONFIRM},
|
|
|
|
|
{"CMSG_GROUP_INVITE", LogicalOpcode::CMSG_GROUP_INVITE},
|
|
|
|
|
{"SMSG_GROUP_INVITE", LogicalOpcode::SMSG_GROUP_INVITE},
|
|
|
|
|
{"CMSG_GROUP_ACCEPT", LogicalOpcode::CMSG_GROUP_ACCEPT},
|
|
|
|
|
{"CMSG_GROUP_DECLINE", LogicalOpcode::CMSG_GROUP_DECLINE},
|
|
|
|
|
{"SMSG_GROUP_DECLINE", LogicalOpcode::SMSG_GROUP_DECLINE},
|
|
|
|
|
{"CMSG_GROUP_UNINVITE_GUID", LogicalOpcode::CMSG_GROUP_UNINVITE_GUID},
|
|
|
|
|
{"SMSG_GROUP_UNINVITE", LogicalOpcode::SMSG_GROUP_UNINVITE},
|
|
|
|
|
{"CMSG_GROUP_SET_LEADER", LogicalOpcode::CMSG_GROUP_SET_LEADER},
|
|
|
|
|
{"SMSG_GROUP_SET_LEADER", LogicalOpcode::SMSG_GROUP_SET_LEADER},
|
|
|
|
|
{"CMSG_GROUP_DISBAND", LogicalOpcode::CMSG_GROUP_DISBAND},
|
|
|
|
|
{"SMSG_GROUP_LIST", LogicalOpcode::SMSG_GROUP_LIST},
|
|
|
|
|
{"SMSG_PARTY_COMMAND_RESULT", LogicalOpcode::SMSG_PARTY_COMMAND_RESULT},
|
2026-02-20 02:19:17 -08:00
|
|
|
{"SMSG_PARTYKILLLOG", LogicalOpcode::SMSG_PARTYKILLLOG},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"MSG_RAID_TARGET_UPDATE", LogicalOpcode::MSG_RAID_TARGET_UPDATE},
|
|
|
|
|
{"CMSG_REQUEST_RAID_INFO", LogicalOpcode::CMSG_REQUEST_RAID_INFO},
|
|
|
|
|
{"SMSG_RAID_INSTANCE_INFO", LogicalOpcode::SMSG_RAID_INSTANCE_INFO},
|
|
|
|
|
{"CMSG_AUTOSTORE_LOOT_ITEM", LogicalOpcode::CMSG_AUTOSTORE_LOOT_ITEM},
|
|
|
|
|
{"CMSG_LOOT", LogicalOpcode::CMSG_LOOT},
|
|
|
|
|
{"CMSG_LOOT_MONEY", LogicalOpcode::CMSG_LOOT_MONEY},
|
|
|
|
|
{"CMSG_LOOT_RELEASE", LogicalOpcode::CMSG_LOOT_RELEASE},
|
|
|
|
|
{"SMSG_LOOT_RESPONSE", LogicalOpcode::SMSG_LOOT_RESPONSE},
|
|
|
|
|
{"SMSG_LOOT_RELEASE_RESPONSE", LogicalOpcode::SMSG_LOOT_RELEASE_RESPONSE},
|
|
|
|
|
{"SMSG_LOOT_REMOVED", LogicalOpcode::SMSG_LOOT_REMOVED},
|
|
|
|
|
{"SMSG_LOOT_MONEY_NOTIFY", LogicalOpcode::SMSG_LOOT_MONEY_NOTIFY},
|
|
|
|
|
{"SMSG_LOOT_CLEAR_MONEY", LogicalOpcode::SMSG_LOOT_CLEAR_MONEY},
|
|
|
|
|
{"CMSG_ACTIVATETAXI", LogicalOpcode::CMSG_ACTIVATETAXI},
|
|
|
|
|
{"CMSG_GOSSIP_HELLO", LogicalOpcode::CMSG_GOSSIP_HELLO},
|
|
|
|
|
{"CMSG_GOSSIP_SELECT_OPTION", LogicalOpcode::CMSG_GOSSIP_SELECT_OPTION},
|
|
|
|
|
{"SMSG_GOSSIP_MESSAGE", LogicalOpcode::SMSG_GOSSIP_MESSAGE},
|
|
|
|
|
{"SMSG_GOSSIP_COMPLETE", LogicalOpcode::SMSG_GOSSIP_COMPLETE},
|
|
|
|
|
{"SMSG_NPC_TEXT_UPDATE", LogicalOpcode::SMSG_NPC_TEXT_UPDATE},
|
|
|
|
|
{"CMSG_GAMEOBJECT_USE", LogicalOpcode::CMSG_GAMEOBJECT_USE},
|
|
|
|
|
{"CMSG_QUESTGIVER_STATUS_QUERY", LogicalOpcode::CMSG_QUESTGIVER_STATUS_QUERY},
|
|
|
|
|
{"SMSG_QUESTGIVER_STATUS", LogicalOpcode::SMSG_QUESTGIVER_STATUS},
|
|
|
|
|
{"SMSG_QUESTGIVER_STATUS_MULTIPLE", LogicalOpcode::SMSG_QUESTGIVER_STATUS_MULTIPLE},
|
|
|
|
|
{"CMSG_QUESTGIVER_HELLO", LogicalOpcode::CMSG_QUESTGIVER_HELLO},
|
2026-02-19 02:53:44 -08:00
|
|
|
{"SMSG_QUESTGIVER_QUEST_LIST", LogicalOpcode::SMSG_QUESTGIVER_QUEST_LIST},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_QUESTGIVER_QUERY_QUEST", LogicalOpcode::CMSG_QUESTGIVER_QUERY_QUEST},
|
|
|
|
|
{"SMSG_QUESTGIVER_QUEST_DETAILS", LogicalOpcode::SMSG_QUESTGIVER_QUEST_DETAILS},
|
|
|
|
|
{"CMSG_QUESTGIVER_ACCEPT_QUEST", LogicalOpcode::CMSG_QUESTGIVER_ACCEPT_QUEST},
|
|
|
|
|
{"CMSG_QUESTGIVER_COMPLETE_QUEST", LogicalOpcode::CMSG_QUESTGIVER_COMPLETE_QUEST},
|
|
|
|
|
{"SMSG_QUESTGIVER_REQUEST_ITEMS", LogicalOpcode::SMSG_QUESTGIVER_REQUEST_ITEMS},
|
|
|
|
|
{"CMSG_QUESTGIVER_REQUEST_REWARD", LogicalOpcode::CMSG_QUESTGIVER_REQUEST_REWARD},
|
|
|
|
|
{"SMSG_QUESTGIVER_OFFER_REWARD", LogicalOpcode::SMSG_QUESTGIVER_OFFER_REWARD},
|
|
|
|
|
{"CMSG_QUESTGIVER_CHOOSE_REWARD", LogicalOpcode::CMSG_QUESTGIVER_CHOOSE_REWARD},
|
|
|
|
|
{"SMSG_QUESTGIVER_QUEST_INVALID", LogicalOpcode::SMSG_QUESTGIVER_QUEST_INVALID},
|
|
|
|
|
{"SMSG_QUESTGIVER_QUEST_COMPLETE", LogicalOpcode::SMSG_QUESTGIVER_QUEST_COMPLETE},
|
|
|
|
|
{"CMSG_QUESTLOG_REMOVE_QUEST", LogicalOpcode::CMSG_QUESTLOG_REMOVE_QUEST},
|
|
|
|
|
{"SMSG_QUESTUPDATE_ADD_KILL", LogicalOpcode::SMSG_QUESTUPDATE_ADD_KILL},
|
2026-02-18 04:06:14 -08:00
|
|
|
{"SMSG_QUESTUPDATE_ADD_ITEM", LogicalOpcode::SMSG_QUESTUPDATE_ADD_ITEM},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_QUESTUPDATE_COMPLETE", LogicalOpcode::SMSG_QUESTUPDATE_COMPLETE},
|
2026-02-18 23:26:58 -08:00
|
|
|
{"SMSG_QUEST_FORCE_REMOVE", LogicalOpcode::SMSG_QUEST_FORCE_REMOVE},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_QUEST_QUERY", LogicalOpcode::CMSG_QUEST_QUERY},
|
|
|
|
|
{"SMSG_QUEST_QUERY_RESPONSE", LogicalOpcode::SMSG_QUEST_QUERY_RESPONSE},
|
|
|
|
|
{"SMSG_QUESTLOG_FULL", LogicalOpcode::SMSG_QUESTLOG_FULL},
|
|
|
|
|
{"CMSG_LIST_INVENTORY", LogicalOpcode::CMSG_LIST_INVENTORY},
|
|
|
|
|
{"SMSG_LIST_INVENTORY", LogicalOpcode::SMSG_LIST_INVENTORY},
|
|
|
|
|
{"CMSG_SELL_ITEM", LogicalOpcode::CMSG_SELL_ITEM},
|
|
|
|
|
{"SMSG_SELL_ITEM", LogicalOpcode::SMSG_SELL_ITEM},
|
|
|
|
|
{"CMSG_BUY_ITEM", LogicalOpcode::CMSG_BUY_ITEM},
|
2026-02-19 16:17:06 -08:00
|
|
|
{"CMSG_BUYBACK_ITEM", LogicalOpcode::CMSG_BUYBACK_ITEM},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_BUY_FAILED", LogicalOpcode::SMSG_BUY_FAILED},
|
|
|
|
|
{"CMSG_TRAINER_LIST", LogicalOpcode::CMSG_TRAINER_LIST},
|
|
|
|
|
{"SMSG_TRAINER_LIST", LogicalOpcode::SMSG_TRAINER_LIST},
|
|
|
|
|
{"CMSG_TRAINER_BUY_SPELL", LogicalOpcode::CMSG_TRAINER_BUY_SPELL},
|
|
|
|
|
{"SMSG_TRAINER_BUY_FAILED", LogicalOpcode::SMSG_TRAINER_BUY_FAILED},
|
|
|
|
|
{"CMSG_ITEM_QUERY_SINGLE", LogicalOpcode::CMSG_ITEM_QUERY_SINGLE},
|
|
|
|
|
{"SMSG_ITEM_QUERY_SINGLE_RESPONSE", LogicalOpcode::SMSG_ITEM_QUERY_SINGLE_RESPONSE},
|
|
|
|
|
{"CMSG_USE_ITEM", LogicalOpcode::CMSG_USE_ITEM},
|
|
|
|
|
{"CMSG_AUTOEQUIP_ITEM", LogicalOpcode::CMSG_AUTOEQUIP_ITEM},
|
|
|
|
|
{"CMSG_SWAP_ITEM", LogicalOpcode::CMSG_SWAP_ITEM},
|
|
|
|
|
{"CMSG_SWAP_INV_ITEM", LogicalOpcode::CMSG_SWAP_INV_ITEM},
|
|
|
|
|
{"SMSG_INVENTORY_CHANGE_FAILURE", LogicalOpcode::SMSG_INVENTORY_CHANGE_FAILURE},
|
|
|
|
|
{"CMSG_INSPECT", LogicalOpcode::CMSG_INSPECT},
|
|
|
|
|
{"SMSG_INSPECT_RESULTS", LogicalOpcode::SMSG_INSPECT_RESULTS},
|
|
|
|
|
{"CMSG_REPOP_REQUEST", LogicalOpcode::CMSG_REPOP_REQUEST},
|
|
|
|
|
{"SMSG_RESURRECT_REQUEST", LogicalOpcode::SMSG_RESURRECT_REQUEST},
|
|
|
|
|
{"CMSG_RESURRECT_RESPONSE", LogicalOpcode::CMSG_RESURRECT_RESPONSE},
|
|
|
|
|
{"CMSG_SPIRIT_HEALER_ACTIVATE", LogicalOpcode::CMSG_SPIRIT_HEALER_ACTIVATE},
|
|
|
|
|
{"SMSG_SPIRIT_HEALER_CONFIRM", LogicalOpcode::SMSG_SPIRIT_HEALER_CONFIRM},
|
|
|
|
|
{"SMSG_RESURRECT_CANCEL", LogicalOpcode::SMSG_RESURRECT_CANCEL},
|
|
|
|
|
{"MSG_MOVE_TELEPORT_ACK", LogicalOpcode::MSG_MOVE_TELEPORT_ACK},
|
|
|
|
|
{"SMSG_TRANSFER_PENDING", LogicalOpcode::SMSG_TRANSFER_PENDING},
|
|
|
|
|
{"SMSG_NEW_WORLD", LogicalOpcode::SMSG_NEW_WORLD},
|
|
|
|
|
{"MSG_MOVE_WORLDPORT_ACK", LogicalOpcode::MSG_MOVE_WORLDPORT_ACK},
|
|
|
|
|
{"SMSG_TRANSFER_ABORTED", LogicalOpcode::SMSG_TRANSFER_ABORTED},
|
|
|
|
|
{"SMSG_FORCE_RUN_SPEED_CHANGE", LogicalOpcode::SMSG_FORCE_RUN_SPEED_CHANGE},
|
2026-02-18 23:26:58 -08:00
|
|
|
{"SMSG_CLIENT_CONTROL_UPDATE", LogicalOpcode::SMSG_CLIENT_CONTROL_UPDATE},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_FORCE_RUN_SPEED_CHANGE_ACK", LogicalOpcode::CMSG_FORCE_RUN_SPEED_CHANGE_ACK},
|
|
|
|
|
{"CMSG_CANCEL_MOUNT_AURA", LogicalOpcode::CMSG_CANCEL_MOUNT_AURA},
|
|
|
|
|
{"SMSG_SHOWTAXINODES", LogicalOpcode::SMSG_SHOWTAXINODES},
|
|
|
|
|
{"SMSG_ACTIVATETAXIREPLY", LogicalOpcode::SMSG_ACTIVATETAXIREPLY},
|
2026-02-20 01:13:01 -08:00
|
|
|
{"SMSG_STANDSTATE_UPDATE", LogicalOpcode::SMSG_STANDSTATE_UPDATE},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"SMSG_NEW_TAXI_PATH", LogicalOpcode::SMSG_NEW_TAXI_PATH},
|
|
|
|
|
{"CMSG_ACTIVATETAXIEXPRESS", LogicalOpcode::CMSG_ACTIVATETAXIEXPRESS},
|
|
|
|
|
{"SMSG_BATTLEFIELD_PORT_DENIED", LogicalOpcode::SMSG_BATTLEFIELD_PORT_DENIED},
|
|
|
|
|
{"SMSG_REMOVED_FROM_PVP_QUEUE", LogicalOpcode::SMSG_REMOVED_FROM_PVP_QUEUE},
|
|
|
|
|
{"SMSG_TRAINER_BUY_SUCCEEDED", LogicalOpcode::SMSG_TRAINER_BUY_SUCCEEDED},
|
|
|
|
|
{"SMSG_BINDPOINTUPDATE", LogicalOpcode::SMSG_BINDPOINTUPDATE},
|
2026-02-18 23:14:01 -08:00
|
|
|
{"SMSG_SET_PROFICIENCY", LogicalOpcode::SMSG_SET_PROFICIENCY},
|
|
|
|
|
{"SMSG_ACTION_BUTTONS", LogicalOpcode::SMSG_ACTION_BUTTONS},
|
|
|
|
|
{"SMSG_LEVELUP_INFO", LogicalOpcode::SMSG_LEVELUP_INFO},
|
2026-02-20 02:21:04 -08:00
|
|
|
{"SMSG_LEVELUP_INFO_ALT", LogicalOpcode::SMSG_LEVELUP_INFO_ALT},
|
|
|
|
|
{"SMSG_PLAY_SOUND", LogicalOpcode::SMSG_PLAY_SOUND},
|
2026-02-18 23:14:01 -08:00
|
|
|
{"CMSG_TAXINODE_STATUS_QUERY", LogicalOpcode::CMSG_TAXINODE_STATUS_QUERY},
|
|
|
|
|
{"SMSG_TAXINODE_STATUS", LogicalOpcode::SMSG_TAXINODE_STATUS},
|
|
|
|
|
{"CMSG_UPDATE_ACCOUNT_DATA", LogicalOpcode::CMSG_UPDATE_ACCOUNT_DATA},
|
2026-02-12 22:56:36 -08:00
|
|
|
{"CMSG_BATTLEFIELD_LIST", LogicalOpcode::CMSG_BATTLEFIELD_LIST},
|
|
|
|
|
{"SMSG_BATTLEFIELD_LIST", LogicalOpcode::SMSG_BATTLEFIELD_LIST},
|
|
|
|
|
{"CMSG_BATTLEFIELD_JOIN", LogicalOpcode::CMSG_BATTLEFIELD_JOIN},
|
|
|
|
|
{"CMSG_BATTLEFIELD_STATUS", LogicalOpcode::CMSG_BATTLEFIELD_STATUS},
|
|
|
|
|
{"SMSG_BATTLEFIELD_STATUS", LogicalOpcode::SMSG_BATTLEFIELD_STATUS},
|
|
|
|
|
{"CMSG_BATTLEFIELD_PORT", LogicalOpcode::CMSG_BATTLEFIELD_PORT},
|
|
|
|
|
{"CMSG_BATTLEMASTER_HELLO", LogicalOpcode::CMSG_BATTLEMASTER_HELLO},
|
|
|
|
|
{"MSG_PVP_LOG_DATA", LogicalOpcode::MSG_PVP_LOG_DATA},
|
|
|
|
|
{"CMSG_LEAVE_BATTLEFIELD", LogicalOpcode::CMSG_LEAVE_BATTLEFIELD},
|
|
|
|
|
{"SMSG_GROUP_JOINED_BATTLEGROUND", LogicalOpcode::SMSG_GROUP_JOINED_BATTLEGROUND},
|
|
|
|
|
{"MSG_BATTLEGROUND_PLAYER_POSITIONS", LogicalOpcode::MSG_BATTLEGROUND_PLAYER_POSITIONS},
|
|
|
|
|
{"SMSG_BATTLEGROUND_PLAYER_JOINED", LogicalOpcode::SMSG_BATTLEGROUND_PLAYER_JOINED},
|
|
|
|
|
{"SMSG_BATTLEGROUND_PLAYER_LEFT", LogicalOpcode::SMSG_BATTLEGROUND_PLAYER_LEFT},
|
|
|
|
|
{"CMSG_BATTLEMASTER_JOIN", LogicalOpcode::CMSG_BATTLEMASTER_JOIN},
|
|
|
|
|
{"SMSG_JOINED_BATTLEGROUND_QUEUE", LogicalOpcode::SMSG_JOINED_BATTLEGROUND_QUEUE},
|
|
|
|
|
{"CMSG_ARENA_TEAM_CREATE", LogicalOpcode::CMSG_ARENA_TEAM_CREATE},
|
|
|
|
|
{"SMSG_ARENA_TEAM_COMMAND_RESULT", LogicalOpcode::SMSG_ARENA_TEAM_COMMAND_RESULT},
|
|
|
|
|
{"CMSG_ARENA_TEAM_QUERY", LogicalOpcode::CMSG_ARENA_TEAM_QUERY},
|
|
|
|
|
{"SMSG_ARENA_TEAM_QUERY_RESPONSE", LogicalOpcode::SMSG_ARENA_TEAM_QUERY_RESPONSE},
|
|
|
|
|
{"CMSG_ARENA_TEAM_ROSTER", LogicalOpcode::CMSG_ARENA_TEAM_ROSTER},
|
|
|
|
|
{"SMSG_ARENA_TEAM_ROSTER", LogicalOpcode::SMSG_ARENA_TEAM_ROSTER},
|
|
|
|
|
{"CMSG_ARENA_TEAM_INVITE", LogicalOpcode::CMSG_ARENA_TEAM_INVITE},
|
|
|
|
|
{"SMSG_ARENA_TEAM_INVITE", LogicalOpcode::SMSG_ARENA_TEAM_INVITE},
|
|
|
|
|
{"CMSG_ARENA_TEAM_ACCEPT", LogicalOpcode::CMSG_ARENA_TEAM_ACCEPT},
|
|
|
|
|
{"CMSG_ARENA_TEAM_DECLINE", LogicalOpcode::CMSG_ARENA_TEAM_DECLINE},
|
|
|
|
|
{"CMSG_ARENA_TEAM_LEAVE", LogicalOpcode::CMSG_ARENA_TEAM_LEAVE},
|
|
|
|
|
{"CMSG_ARENA_TEAM_REMOVE", LogicalOpcode::CMSG_ARENA_TEAM_REMOVE},
|
|
|
|
|
{"CMSG_ARENA_TEAM_DISBAND", LogicalOpcode::CMSG_ARENA_TEAM_DISBAND},
|
|
|
|
|
{"CMSG_ARENA_TEAM_LEADER", LogicalOpcode::CMSG_ARENA_TEAM_LEADER},
|
|
|
|
|
{"SMSG_ARENA_TEAM_EVENT", LogicalOpcode::SMSG_ARENA_TEAM_EVENT},
|
|
|
|
|
{"CMSG_BATTLEMASTER_JOIN_ARENA", LogicalOpcode::CMSG_BATTLEMASTER_JOIN_ARENA},
|
|
|
|
|
{"SMSG_ARENA_TEAM_STATS", LogicalOpcode::SMSG_ARENA_TEAM_STATS},
|
|
|
|
|
{"SMSG_ARENA_ERROR", LogicalOpcode::SMSG_ARENA_ERROR},
|
|
|
|
|
{"MSG_INSPECT_ARENA_TEAMS", LogicalOpcode::MSG_INSPECT_ARENA_TEAMS},
|
2026-02-17 17:59:41 -08:00
|
|
|
{"SMSG_WEATHER", LogicalOpcode::SMSG_WEATHER},
|
2026-02-14 14:30:09 -08:00
|
|
|
{"CMSG_EMOTE", LogicalOpcode::CMSG_EMOTE},
|
|
|
|
|
{"SMSG_EMOTE", LogicalOpcode::SMSG_EMOTE},
|
|
|
|
|
{"CMSG_TEXT_EMOTE", LogicalOpcode::CMSG_TEXT_EMOTE},
|
|
|
|
|
{"SMSG_TEXT_EMOTE", LogicalOpcode::SMSG_TEXT_EMOTE},
|
|
|
|
|
{"CMSG_JOIN_CHANNEL", LogicalOpcode::CMSG_JOIN_CHANNEL},
|
|
|
|
|
{"CMSG_LEAVE_CHANNEL", LogicalOpcode::CMSG_LEAVE_CHANNEL},
|
|
|
|
|
{"SMSG_CHANNEL_NOTIFY", LogicalOpcode::SMSG_CHANNEL_NOTIFY},
|
|
|
|
|
{"CMSG_CHANNEL_LIST", LogicalOpcode::CMSG_CHANNEL_LIST},
|
|
|
|
|
{"SMSG_CHANNEL_LIST", LogicalOpcode::SMSG_CHANNEL_LIST},
|
2026-02-14 15:05:18 -08:00
|
|
|
{"SMSG_INSPECT_TALENT", LogicalOpcode::SMSG_INSPECT_TALENT},
|
2026-02-15 14:00:41 -08:00
|
|
|
// Mail
|
|
|
|
|
{"SMSG_SHOW_MAILBOX", LogicalOpcode::SMSG_SHOW_MAILBOX},
|
|
|
|
|
{"CMSG_GET_MAIL_LIST", LogicalOpcode::CMSG_GET_MAIL_LIST},
|
|
|
|
|
{"SMSG_MAIL_LIST_RESULT", LogicalOpcode::SMSG_MAIL_LIST_RESULT},
|
|
|
|
|
{"CMSG_SEND_MAIL", LogicalOpcode::CMSG_SEND_MAIL},
|
|
|
|
|
{"SMSG_SEND_MAIL_RESULT", LogicalOpcode::SMSG_SEND_MAIL_RESULT},
|
|
|
|
|
{"CMSG_MAIL_TAKE_MONEY", LogicalOpcode::CMSG_MAIL_TAKE_MONEY},
|
|
|
|
|
{"CMSG_MAIL_TAKE_ITEM", LogicalOpcode::CMSG_MAIL_TAKE_ITEM},
|
|
|
|
|
{"CMSG_MAIL_DELETE", LogicalOpcode::CMSG_MAIL_DELETE},
|
|
|
|
|
{"CMSG_MAIL_MARK_AS_READ", LogicalOpcode::CMSG_MAIL_MARK_AS_READ},
|
|
|
|
|
{"SMSG_RECEIVED_MAIL", LogicalOpcode::SMSG_RECEIVED_MAIL},
|
|
|
|
|
{"MSG_QUERY_NEXT_MAIL_TIME", LogicalOpcode::MSG_QUERY_NEXT_MAIL_TIME},
|
Implement bank, guild bank, and auction house systems
Add 27 new opcodes, packet builders/parsers, handler methods, inventory
extension with 28 bank slots + 7 bank bags, and UI windows for personal
bank, guild bank (6 tabs x 98 slots), and auction house (browse/sell/bid).
Fix Classic gossip parser to omit boxMoney/boxText fields not present in
Vanilla protocol, fix gossip icon labels with text-based NPC type detection,
and add Turtle WoW opcode mappings for bank and auction interactions.
2026-02-16 21:11:18 -08:00
|
|
|
// Bank
|
|
|
|
|
{"CMSG_BANKER_ACTIVATE", LogicalOpcode::CMSG_BANKER_ACTIVATE},
|
|
|
|
|
{"SMSG_SHOW_BANK", LogicalOpcode::SMSG_SHOW_BANK},
|
|
|
|
|
{"CMSG_BUY_BANK_SLOT", LogicalOpcode::CMSG_BUY_BANK_SLOT},
|
|
|
|
|
{"SMSG_BUY_BANK_SLOT_RESULT", LogicalOpcode::SMSG_BUY_BANK_SLOT_RESULT},
|
|
|
|
|
{"CMSG_AUTOBANK_ITEM", LogicalOpcode::CMSG_AUTOBANK_ITEM},
|
|
|
|
|
{"CMSG_AUTOSTORE_BANK_ITEM", LogicalOpcode::CMSG_AUTOSTORE_BANK_ITEM},
|
|
|
|
|
// Guild Bank
|
|
|
|
|
{"CMSG_GUILD_BANKER_ACTIVATE", LogicalOpcode::CMSG_GUILD_BANKER_ACTIVATE},
|
|
|
|
|
{"CMSG_GUILD_BANK_QUERY_TAB", LogicalOpcode::CMSG_GUILD_BANK_QUERY_TAB},
|
|
|
|
|
{"SMSG_GUILD_BANK_LIST", LogicalOpcode::SMSG_GUILD_BANK_LIST},
|
|
|
|
|
{"CMSG_GUILD_BANK_SWAP_ITEMS", LogicalOpcode::CMSG_GUILD_BANK_SWAP_ITEMS},
|
|
|
|
|
{"CMSG_GUILD_BANK_BUY_TAB", LogicalOpcode::CMSG_GUILD_BANK_BUY_TAB},
|
|
|
|
|
{"CMSG_GUILD_BANK_UPDATE_TAB", LogicalOpcode::CMSG_GUILD_BANK_UPDATE_TAB},
|
|
|
|
|
{"CMSG_GUILD_BANK_DEPOSIT_MONEY", LogicalOpcode::CMSG_GUILD_BANK_DEPOSIT_MONEY},
|
|
|
|
|
{"CMSG_GUILD_BANK_WITHDRAW_MONEY", LogicalOpcode::CMSG_GUILD_BANK_WITHDRAW_MONEY},
|
|
|
|
|
// Auction House
|
|
|
|
|
{"MSG_AUCTION_HELLO", LogicalOpcode::MSG_AUCTION_HELLO},
|
|
|
|
|
{"CMSG_AUCTION_SELL_ITEM", LogicalOpcode::CMSG_AUCTION_SELL_ITEM},
|
|
|
|
|
{"CMSG_AUCTION_REMOVE_ITEM", LogicalOpcode::CMSG_AUCTION_REMOVE_ITEM},
|
|
|
|
|
{"CMSG_AUCTION_LIST_ITEMS", LogicalOpcode::CMSG_AUCTION_LIST_ITEMS},
|
|
|
|
|
{"CMSG_AUCTION_LIST_OWNER_ITEMS", LogicalOpcode::CMSG_AUCTION_LIST_OWNER_ITEMS},
|
|
|
|
|
{"CMSG_AUCTION_PLACE_BID", LogicalOpcode::CMSG_AUCTION_PLACE_BID},
|
|
|
|
|
{"SMSG_AUCTION_COMMAND_RESULT", LogicalOpcode::SMSG_AUCTION_COMMAND_RESULT},
|
|
|
|
|
{"SMSG_AUCTION_LIST_RESULT", LogicalOpcode::SMSG_AUCTION_LIST_RESULT},
|
|
|
|
|
{"SMSG_AUCTION_OWNER_LIST_RESULT", LogicalOpcode::SMSG_AUCTION_OWNER_LIST_RESULT},
|
|
|
|
|
{"SMSG_AUCTION_BIDDER_LIST_RESULT", LogicalOpcode::SMSG_AUCTION_BIDDER_LIST_RESULT},
|
|
|
|
|
{"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},
|
2026-02-18 23:42:28 -08:00
|
|
|
{"SMSG_UNKNOWN_319", LogicalOpcode::SMSG_UNKNOWN_319},
|
2026-02-12 22:56:36 -08:00
|
|
|
};
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
|
|
static constexpr size_t kOpcodeNameCount = sizeof(kOpcodeNames) / sizeof(kOpcodeNames[0]);
|
|
|
|
|
|
|
|
|
|
std::optional<LogicalOpcode> OpcodeTable::nameToLogical(const std::string& name) {
|
|
|
|
|
for (size_t i = 0; i < kOpcodeNameCount; ++i) {
|
|
|
|
|
if (name == kOpcodeNames[i].name) return kOpcodeNames[i].op;
|
|
|
|
|
}
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* OpcodeTable::logicalToName(LogicalOpcode op) {
|
|
|
|
|
uint16_t val = static_cast<uint16_t>(op);
|
|
|
|
|
for (size_t i = 0; i < kOpcodeNameCount; ++i) {
|
|
|
|
|
if (static_cast<uint16_t>(kOpcodeNames[i].op) == val) return kOpcodeNames[i].name;
|
|
|
|
|
}
|
|
|
|
|
return "UNKNOWN";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool OpcodeTable::loadFromJson(const std::string& path) {
|
|
|
|
|
std::ifstream f(path);
|
|
|
|
|
if (!f.is_open()) {
|
|
|
|
|
LOG_WARNING("OpcodeTable: cannot open ", path, ", using defaults");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string json((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
|
|
|
|
|
2026-02-20 00:39:20 -08:00
|
|
|
// Start fresh — JSON is the single source of truth for opcode mappings.
|
|
|
|
|
logicalToWire_.clear();
|
|
|
|
|
wireToLogical_.clear();
|
2026-02-13 16:53:28 -08:00
|
|
|
|
2026-02-12 22:56:36 -08:00
|
|
|
// Parse simple JSON: { "NAME": "0xHEX", ... } or { "NAME": 123, ... }
|
|
|
|
|
size_t pos = 0;
|
|
|
|
|
size_t loaded = 0;
|
|
|
|
|
while (pos < json.size()) {
|
|
|
|
|
// Find next quoted key
|
|
|
|
|
size_t keyStart = json.find('"', pos);
|
|
|
|
|
if (keyStart == std::string::npos) break;
|
|
|
|
|
size_t keyEnd = json.find('"', keyStart + 1);
|
|
|
|
|
if (keyEnd == std::string::npos) break;
|
|
|
|
|
std::string key = json.substr(keyStart + 1, keyEnd - keyStart - 1);
|
|
|
|
|
|
|
|
|
|
// Find colon then value
|
|
|
|
|
size_t colon = json.find(':', keyEnd);
|
|
|
|
|
if (colon == std::string::npos) break;
|
|
|
|
|
|
|
|
|
|
// Skip whitespace
|
|
|
|
|
size_t valStart = colon + 1;
|
|
|
|
|
while (valStart < json.size() && (json[valStart] == ' ' || json[valStart] == '\t' ||
|
|
|
|
|
json[valStart] == '\r' || json[valStart] == '\n' || json[valStart] == '"'))
|
|
|
|
|
++valStart;
|
|
|
|
|
|
|
|
|
|
size_t valEnd = json.find_first_of(",}\"\r\n", valStart);
|
|
|
|
|
if (valEnd == std::string::npos) valEnd = json.size();
|
|
|
|
|
std::string valStr = json.substr(valStart, valEnd - valStart);
|
|
|
|
|
|
|
|
|
|
// Parse hex or decimal value
|
|
|
|
|
uint16_t wire = 0;
|
|
|
|
|
try {
|
|
|
|
|
if (valStr.size() > 2 && (valStr[0] == '0' && (valStr[1] == 'x' || valStr[1] == 'X'))) {
|
|
|
|
|
wire = static_cast<uint16_t>(std::stoul(valStr, nullptr, 16));
|
|
|
|
|
} else {
|
|
|
|
|
wire = static_cast<uint16_t>(std::stoul(valStr));
|
|
|
|
|
}
|
|
|
|
|
} catch (...) {
|
|
|
|
|
pos = valEnd + 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto logOp = nameToLogical(key);
|
|
|
|
|
if (logOp) {
|
|
|
|
|
uint16_t logIdx = static_cast<uint16_t>(*logOp);
|
|
|
|
|
logicalToWire_[logIdx] = wire;
|
|
|
|
|
wireToLogical_[wire] = logIdx;
|
|
|
|
|
++loaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pos = valEnd + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-13 16:53:28 -08:00
|
|
|
if (loaded == 0) {
|
2026-02-20 00:39:20 -08:00
|
|
|
LOG_WARNING("OpcodeTable: no opcodes loaded from ", path);
|
2026-02-13 16:53:28 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-12 22:56:36 -08:00
|
|
|
LOG_INFO("OpcodeTable: loaded ", loaded, " opcodes from ", path);
|
2026-02-13 16:53:28 -08:00
|
|
|
return true;
|
2026-02-12 22:56:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint16_t OpcodeTable::toWire(LogicalOpcode op) const {
|
|
|
|
|
auto it = logicalToWire_.find(static_cast<uint16_t>(op));
|
|
|
|
|
return (it != logicalToWire_.end()) ? it->second : 0xFFFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::optional<LogicalOpcode> OpcodeTable::fromWire(uint16_t wireValue) const {
|
|
|
|
|
auto it = wireToLogical_.find(wireValue);
|
|
|
|
|
if (it != wireToLogical_.end()) {
|
|
|
|
|
return static_cast<LogicalOpcode>(it->second);
|
|
|
|
|
}
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool OpcodeTable::hasOpcode(LogicalOpcode op) const {
|
|
|
|
|
return logicalToWire_.count(static_cast<uint16_t>(op)) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace game
|
|
|
|
|
} // namespace wowee
|