Mangos的指令處理函數(shù)(opcodes handlers)
(轉(zhuǎn)載請(qǐng)注明來(lái)源于金慶的專欄)
WorldSession中總共有300多個(gè)指令包處理函數(shù), 以Handle開頭, 無(wú)返回值, 參數(shù)為WorldPacket&. 例如:void HandleCharEnumOpcode(WorldPacket& recvPacket);處理函數(shù)按功能分散在多個(gè)XXXHandler.cpp中實(shí)現(xiàn). 例如: ArenaTeamHandler.cpp, AuctionHouseHandler.cpp.有一個(gè)文件名例外: Mail.cpp.只有4個(gè)在WorldSession.cpp中實(shí)現(xiàn), Handle后有下劃線表示區(qū)別.這4個(gè)都是空操作, 僅有日志記錄.void Handle_NULL(WorldPacket& recvPacket); // not usedvoid Handle_EarlyProccess( WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnReadvoid Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from clientvoid 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是操作碼表, 每個(gè)操作碼對(duì)應(yīng)一個(gè)OpcodeHandler結(jié)構(gòu), 目前有1000多個(gè)操作碼.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個(gè)字段: 名字, 狀態(tài), 處理函數(shù):struct OpcodeHandler{ char const* name; SessionStatus status; void (WorldSession::*handler)(WorldPacket& recvPacket);};名字用于日志輸出. 狀態(tài)有4種, 表示用戶必須處于該狀態(tài)才能進(jìn)入處理函數(shù)./// Player stateenum 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多個(gè), 但實(shí)際的處理函數(shù)不到400個(gè), 因?yàn)榇蟛糠质荢TATUS_NEVER, 對(duì)應(yīng)的處理函數(shù)為上面所述的WorldSession.cpp內(nèi)實(shí)現(xiàn)的4個(gè)空操作.OpcodeHandler.handler是處理函數(shù), 必須是WorldSession的成員函數(shù), 無(wú)返回值, 參數(shù)WorldPacket&.處理函數(shù)的實(shí)現(xiàn)文件--------------------除了Mail.cpp, 處理函數(shù)的實(shí)現(xiàn)文件名以Handler為后綴. 除了Mail.h, NpcHandler.h, 所有實(shí)現(xiàn)只有.cpp文件, 沒(méi)有.h文件. 文件名 功能 Handler個(gè)數(shù) ------ ---- ----------- ArenaTeamHandler.cpp 競(jìng)技場(chǎng)隊(duì)伍 10 AuctionHouseHandler.cpp 拍賣行 8 BattleGroundHandler.cpp 戰(zhàn)場(chǎng) 12 CalendarHandler.cpp 副本日程? 15 ChannelHandler.cpp 聊天頻道 19 CharacterHandler.cpp 角色 22 ChatHandler.cpp 聊天 4 CombatHandler.cpp 戰(zhàn)斗 3 DuelHandler.cpp 決斗 2 GMTicketHandler.cpp GM求助 6 GroupHandler.cpp 隊(duì)伍 24 GuildHandler.cpp 公會(huì) 34 ItemHandler.cpp 物品 23 LFGHandler.cpp 尋找隊(duì)伍 10 LootHandler.cpp 掉落 6 Mail.cpp 郵件 10 MiscHandler.cpp 雜類 56 MovementHandler.cpp 移動(dòng) 15 NPCHandler.cpp NPC 15 PetHandler.cpp 寵物 13 PetitionsHandler.cpp 申請(qǐng)公會(huì) 9 QueryHandler.cpp 查詢 7 QuestHandler.cpp 任務(wù) 16 SkillHandler.cpp 技能 3 SpellHandler.cpp 法術(shù) 13 TaxiHandler.cpp 飛機(jī)系統(tǒng) 5 TradeHandler.cpp 交易 10 VoiceChatHandler.cpp 語(yǔ)音聊天 3
Powered by: C++博客 Copyright © 金慶