Mangos的指令处理函数(opcodes handlers)
(转载请注明来源于金庆的专栏)
WorldSession中总共有300多个指令包处理函数,
以Handle开头, 无返回值, 参数为WorldPacket&. 例如:
void HandleCharEnumOpcode(WorldPacket& recvPacket);
处理函数按功能分散在多个XXXHandler.cpp中实现.
例如: ArenaTeamHandler.cpp, AuctionHouseHandler.cpp.
有一个文件名例外: Mail.cpp.
只有4个在WorldSession.cpp中实现, Handle后有下划线表示区别.
这4个都是空操作, 仅有日志记录.
void Handle_NULL(WorldPacket& recvPacket); // not used
void Handle_EarlyProccess( WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnRead
void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client
void Handle_Deprecated(WorldPacket& recvPacket); // never used anymore by client
指令包处理的入口在WorldSession::Update()中:
while (!_recvQueue.empty())
{
WorldPacket *packet = _recvQueue.next();
OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
...
(this->*opHandle.handler)(*packet);
}
其中opcodeTable是操作码表, 每个操作码对应一个OpcodeHandler结构, 目前有1000多个操作码.
OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
{
/*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL },
...
/*0x4AC*/ { "UMSG_UNKNOWN_1196", STATUS_NEVER, &WorldSession::Handle_NULL },
};
OpcodeHandler有3个字段: 名字, 状态, 处理函数:
struct OpcodeHandler
{
char const* name;
SessionStatus status;
void (WorldSession::*handler)(WorldPacket& recvPacket);
};
名字用于日志输出. 状态有4种, 表示用户必须处于该状态才能进入处理函数.
/// Player state
enum SessionStatus
{
STATUS_AUTHED = 0, ///< Player authenticated
STATUS_LOGGEDIN, ///< Player in game
STATUS_TRANSFER_PENDING, ///< Player transferring to another map
STATUS_NEVER ///< Opcode not accepted from client (deprecated or server side only)
};
操作码1000多个, 但实际的处理函数不到400个, 因为大部分是STATUS_NEVER,
对应的处理函数为上面所述的WorldSession.cpp内实现的4个空操作.
OpcodeHandler.handler是处理函数, 必须是WorldSession的成员函数,
无返回值, 参数WorldPacket&.
处理函数的实现文件
--------------------
除了Mail.cpp, 处理函数的实现文件名以Handler为后缀.
除了Mail.h, NpcHandler.h, 所有实现只有.cpp文件, 没有.h文件.
文件名 功能 Handler个数
------ ---- -----------
ArenaTeamHandler.cpp 竞技场队伍 10
AuctionHouseHandler.cpp 拍卖行 8
BattleGroundHandler.cpp 战场 12
CalendarHandler.cpp 副本日程? 15
ChannelHandler.cpp 聊天频道 19
CharacterHandler.cpp 角色 22
ChatHandler.cpp 聊天 4
CombatHandler.cpp 战斗 3
DuelHandler.cpp 决斗 2
GMTicketHandler.cpp GM求助 6
GroupHandler.cpp 队伍 24
GuildHandler.cpp 公会 34
ItemHandler.cpp 物品 23
LFGHandler.cpp 寻找队伍 10
LootHandler.cpp 掉落 6
Mail.cpp 邮件 10
MiscHandler.cpp 杂类 56
MovementHandler.cpp 移动 15
NPCHandler.cpp NPC 15
PetHandler.cpp 宠物 13
PetitionsHandler.cpp 申请公会 9
QueryHandler.cpp 查询 7
QuestHandler.cpp 任务 16
SkillHandler.cpp 技能 3
SpellHandler.cpp 法术 13
TaxiHandler.cpp 飞机系统 5
TradeHandler.cpp 交易 10
VoiceChatHandler.cpp 语音聊天 3