服务器公共组件实现 -- 状态机

  有关State模式的设计意图及实现就不从设计模式中摘抄了,我们只来看看游戏服务器编程中如何使用State设计模式。

  首先还是从mangos的代码开始看起,我们注意到登录服在处理客户端发来的消息时用到了这样一个结构体:

  struct AuthHandler
  {
    eAuthCmd cmd;
    uint32 status;
    bool (AuthSocket::*handler)(void);
  };

  该结构体定义了每个消息码的处理函数及需要的状态标识,只有当前状态满足要求时才会调用指定的处理函数,否则这个消息码的出现是不合法的。这个status状态标识的定义是一个宏,有两种有效的标识,STATUS_CONNECTED和STATUS_AUTHED,也就是未认证通过和已认证通过。而这个状态标识的改变是在运行时进行的,确切的说是在收到某个消息并正确处理完后改变的。

  我们再来看看设计模式中对State模式的说明,其中关于State模式适用情况里有一条,当操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态,这个状态通常用一个或多个枚举变量表示。

  描述的情况与我们这里所要处理的情况是如此的相似,也许我们可以试一试。那再看看State模式提供的解决方案是怎样的,State模式将每一个条件分支放入一个独立的类中。

  由于这里的两个状态标识只区分出了两种状态,所以,我们仅需要两个独立的类,用以表示两种状态即可。然后,按照State模式的描述,我们还需要一个Context类,也就是状态机管理类,用以管理当前的状态类。稍作整理,大概的代码会类似这样:

  状态基类接口:
  StateBase
  {
    void Enter() = 0;
    void Leave() = 0;
    void Process(Message* msg) = 0;
  };

  状态机基类接口:
  MachineBase
  {
    void ChangeState(StateBase* state) = 0;

    StateBase* m_curState;
  };

  我们的逻辑处理类会从MachineBase派生,当取出数据包后交给当前状态处理,前面描述的两个状态类从StateBase派生,每个状态类只处理该状态标识下需要处理的消息。当要进行状态转换时,调用MachineBase的ChangeState()方法,显示地告诉状态机管理类自己要转到哪一个状态。所以,状态类内部需要保存状态机管理类的指针,这个可以在状态类初始化时传入。具体的实现细节就不做过多描述了。

  使用状态机虽然避免了复杂的判断语句,但也引入了新的麻烦。当我们在进行状态转换时,可能会需要将一些现场数据从老状态对象转移到新状态对象,这需要在定义接口时做一下考虑。如果不希望执行拷贝,那么这里公有的现场数据也可放到状态机类中,只是这样在使用时可能就不那么优雅了。

  正如同在设计模式中所描述的,所有的模式都是已有问题的另一种解决方案,也就是说这并不是唯一的解决方案。放到我们今天讨论的State模式中,就拿登录服所处理的两个状态来说,也许用mangos所采用的遍历处理函数的方法可能更简单,但当系统中的状态数量增多,状态标识也变多的时候,State模式就显得尤其重要了。

  比如在游戏服务器上玩家的状态管理,还有在实现NPC人工智能时的各种状态管理,这些就留作以后的专题吧。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mangos不是一个魔兽私服模拟器,它是一个开源的自由软件项目,是用c++和C#编程语言,实现的一个支持大型多人在线角色扮演游戏服务器的程序框架,在这个框架下,它理论上应该支持任何客户端的网络游戏,由于现在很多人使用魔兽世界来对它进行测试,所以针对魔兽世界的脚本和数据库文件比较完善,很多人就利用这个开源项目来实现魔兽私服。   首先,mangos项目是一个开源的自由软件(如同linux或者firefox),并且遵守其中最为严格的GPL协议,也就是保证源代码绝对的自由,要了解什么是开源软件,自由软件请自己搜索这方面的资料。   其次开发小组一再强调,这是个研究,教育性质的对怎样开发大型网游的服务器端有好处的项目,是一个技术细节毫无保留向公众开放的软件,是一件很有意义的事情,如果你使用它作为盈利目的,那你本身就违反了软件的协议。所以任何利用mangos项目进行私服活动的组织和个人都违反了mangos的宗旨,mangos项目也不会对它们负责。   mangos的技术细节上是这样的,核心部分是个和特定游戏没有关系的核心框架程序,主要是进行进程调度,创造世界,建立心跳机制,处理网络接入等。数据库也是使用的开源数据库软件MySQL,编译器使用的是GCC。至于游戏内容数据库,游戏人物,时间,世界脚本,都是由这个核心程序所支持的扩展脚本来实现,所以有一些独立出来的项目专门模拟魔兽世界来开发支持mangos的核心程序。现在mangos的核心程序已经放到著名的协同开发网站sourceforge上开发了,使用的版本控制工具是subversion,(目前已经迁移到GIT)。大家都可以从sourceforge的subversion数据库中下载最新的源代码程序。   另外有点要注意的是,开源项目是很容易被利用的,有时候有的公司开发了一个软件说是自己做的其实内核都是别人的开源内核,但是公司又不承认,利用了别人的劳动成果赚钱不说,既不回报社区,也对开源自由软件造成了很大的伤害。所以大家注意了,如果看到一个和魔兽世界很像的什么网络游戏?要想想是不是利用的mangos的核心程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值