金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks

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 
                

 


posted on 2009-04-15 18:07 金庆 阅读(1440) 评论(0)  编辑 收藏 引用 所属分类: 1. C/C++2. 网游开发

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理