热血传奇Rungate源代码分析笔记。
来源:互联网 发布:淘宝江南商学院 编辑:程序博客网 时间:2024/04/29 08:03
控制台Socket会每隔一段时间向控制台发送保活包。如果没有发送 那么控制台肯定是知道rungate没反应了或者被关闭了 然后可以立马又开启。纯粹是为了私服假者简单而考 虑。
实际只有2个Socket对象才是最主要的。M2Sokcet和ClientSocket。
整个结构当然是使用的典型生产者消费者模型。 但是代码结构很不清晰.而且消息的处理是使用Timer来处理,而不是线程。
程序在通过一个常量定义了在栈上的会话数量。当程序开始运行会 在栈上有一个数组 保存会话信息。 会话信息是一个结构体,内部记录了会话的信息,比如连接时间,封包大小
以及 上次移动时间 上次通讯时间等等。
当有客户端连接时候。会在预分频的数组内找到一个未使用的空间。初始化这个数组的内容 将当前的客户端连接保持在这个会话之内。
当收到客户端的信息时候,会进行一系列合法的验证 或者保护。最终将消息生成一个消息体:
ReviceMsgList.Add(UserData); //加入收到的消息列表内。
收收到服务端的消息的时候。将消息头部 转换成如下消息格式:
TMsgHeader = packed record dwCode: LongWord; nSocket: Integer; wGSocketIdx: Word; wIdent: Word; wUserListIndex: Integer; nLength: Integer; end;记录了消息的类型 长度 和Socket句柄等消息。根据wIdent的值
case pMsg.wIdent of GM_CHECKSERVER: begin //客户端需要先验证网关 boCheckServerFail := False; dwCheckServerTimeMin := GetTickCount - dwCheckServerTick; if dwCheckServerTimeMin > dwCheckServerTimeMax then dwCheckServerTimeMax := dwCheckServerTimeMin; //dwCheckServerTick := GetTickCount(); end; GM_SERVERUSERINDEX: begin //wGSocketIdx 为服务端的Socket句柄 这句主要是修改wUserListIndex。暂时没看出要干嘛 if (pMsg.wGSocketIdx < RUNATEMAXSESSION) and (pMsg.nSocket = SessionArray[pMsg.wGSocketIdx].nSckHandle) then begin SessionArray[pMsg.wGSocketIdx].nUserListIndex := pMsg.wUserListIndex; end; end; GM_RECEIVE_OK: begin {dwCheckServerTimeMin := GetTickCount - dwCheckRecviceTick; if dwCheckServerTimeMin > dwCheckServerTimeMax then dwCheckServerTimeMax := dwCheckServerTimeMin; dwCheckRecviceTick := GetTickCount(); } SendServerMsg(GM_RECEIVE_OK, 0, 0, 0, 0, nil); //消息到达处理,貌似很没必要吧。应该是M2会做一些处理 end; GM_DATA: begin ProcessMakeSocketStr(pMsg.nSocket, pMsg.wGSocketIdx, MsgBuff, pMsg.nLength);//进行编码处理后 加入到每个会话的列表(实际是string)。此时并不是发送,并将消息加入SendMsgList; end; GM_TEST: begin end;
首先此函数会更新界面显示,(这个耦合性也太大了吧。业务逻辑 跟界面扯上了关系)。
然后将ReviceMsgList内所有的收到的消息发送给M2处理。(客户端发送过来的)
接着将SendMsgList 内所有的消息 投递到客户端(每个消息包括了客户端描述 所以可以知道应该投给哪个客户端)。
然后每2秒向M2发送一个保活包。
总结: 网关收到客户端的包 是直接转发给M2的其中并没有解密。而M2发送给客户端的消息是要经过网关再EncodeMessage。也就是说网关并没有承担起完整的加解密。
M2还要负责客户端的解密操作。可以看出传奇的源码在设计上不太理想。
思考: Srv处理应该主要集中在游戏数据的处理上 而封包的加密解密 应该给游戏网关进行。同时游戏网关内,不宜开多线程进行操作。因为游戏网关面对的资源是整个计算机的 资源。过多的线程可以让单个网关获得比较好的效率。但是游戏网关在设计中并不是让自身获得更好的效率 而是让整个计算机的资源充分的利用。如果自身一个网关无 法处理用户请求的时候,应该开启多个网关协同处理。 所以在网关的设计上应该将发送和接受 编码解码 放在同一个线程内。以多进程取代多线程,以避免在多线程处理 因为生产者消费者模型 而导致两个线程实际只有一个线程在工作。 个人愚见 错误请指正。
- 热血传奇Rungate源代码分析笔记。
- 热血传奇服务端源代码分析笔记
- SharpDevelop源代码分析笔记
- 热血传奇Tile地图绘制方法分析及平滑绘制分析
- 热血传奇Tile地图绘制方法分析及平滑绘制分析
- 关于热血传奇actor绘制的分析与思考
- 关于热血传奇actor绘制的分析与思考
- 热血传奇之资源文件与地图的读取分析
- webbench-1.5源代码分析笔记
- 模版引擎AderTemplate源代码分析笔记
- 开源代码分析的一些笔记
- Libevent源代码分析笔记一,初见libevent
- Libevent源代码分析笔记二,初始化
- Android系统源代码情景分析笔记00
- Linux内核源代码情景分析笔记
- 热血传奇1.85版猜想
- C#热血传奇引用dll
- 源代码分析
- Java中equals方法和==号的区别
- 正确选择报表工具的十大标准
- windows 部署Mongodb时,报由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。 错误
- CSS3的calc()使用(转载自 http://www.w3cplus.com/css3/how-to-use-css3-calc-function.html)
- 微软面试题--翻转数组中的一段,使0为1,1为0,求此数组中1的个数最多
- 热血传奇Rungate源代码分析笔记。
- Improving Word Representations via Global Context and MultipleWord Prototypes
- cocos2dx 常见的49中动作详解
- tips
- 在<HEAD>内使用<LINK>标签
- <java——常用对象API、其他对象>
- CSDN博客去图片水印
- hdu 2686 双线程DP
- Android编译系统(二)