Mangos的指令处理函数

简介:
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                 


本文转自阿汐 51CTO博客,原文链接:http://blog.51cto.com/axiii/150636,如需转载请自行联系原作者


相关文章
|
4月前
|
存储 C语言
对函数的剖析二
对函数的剖析二
29 0
|
4月前
|
存储 编译器
函数(下)
函数(下)
60 0
|
9月前
|
编译器
函函函函函函函函函函函数——two
函函函函函函函函函函函数——two
69 0
函函函函函函函函函函函数——two
|
9月前
|
编译器 C语言
C 中的函数
C 中的函数
|
10月前
实现strcta函数
实现strcta函数
|
12月前
|
Serverless
比值函数
比值函数
152 0
javaSprict 03 函数的使用
本文将讲述javaSprict中函数的声明,调用方法
javaSprict 03 函数的使用
|
JavaScript 前端开发 API
h函数为什么叫h?
h函数为什么叫h?
198 0