Contents
  1. 1. 运营
  2. 2.
  3. 3. 架构
  4. 4. 写的很怪的Node服务器
  5. 5. 规范

运营

最近在做GM工具和日志,为了了解流程向大佬要来一份运营的权限,虽然一些内幕我不能说,但是能够看到dh下所有游戏的运营数据,一时间还是很震撼的。这些运营数据是怎么来的呢,就是服务器这边不厌其烦的输出各种各样的日志,从物品到比赛,从登陆到登出,从充值到消费。基本上这边想查,任何异常数据都是随便查出来的,没有什么查不出来的情况,就是看这边的态度怎么样了。

m3服务器的IPC的流读写部分我原来都当做黑盒在用,因为看不太懂也不想去看,后来发现有些非IPC,比如协议和DB也在用流读写,我就正常反应的点进去看了下发现其实并不复杂。大概就是一个SeNetStream结构体,把读写各种基本类型数据的方法进行分开处理,用读取和移动位置的方法把数据全部存在一个char组里。这样的好处就数据量小,而且解析的方法也比较自然且直观。

1
2
3
4
5
6
7
8
9
10
class SeNetStream
{
public:
// huge code here
protected:
char m_acData[65535];
char* m_pcData;
int m_iSize;
int m_iPos;
};

然后我想这东西这么溜批,用法也简单,把结构体丢进去就好了,之后我发现不是的,你要为每个结构体定义读写方法(就是里面属性的读写顺序)。难怪梦2要用自动化工具,不然每定义一个协议,工作量都不小。

架构

记得第一篇文章的那副架构图吗,我想说的是,这个架构并不是一开始是这样的。一开始基本上全部逻辑都在ws里,包括dbserver,后来发现业务太多就分离了出去。其他服务器情况雷同,比如处理GM和运维请求的那个node服务器。这给我们一个启发,任何东西的原型都是很丑陋的,一开始不要太专注于把它设计的很好,说的程序员一点,就是不要过早优化。

写的很怪的Node服务器

node服务器在解析和发送数据的时候也沿用了那套流的解析方法,以及协议的大量的枚举判断。这样写出来的的代码就充满着诡异的感觉(想想看充满着C++气息的JS代码)。导致我前面很长一段时间只能把这个node服务器当做黑盒用,哪怕到了后面,也完全没有是在写Dynamically的感觉,这是由于工程里硬性规定的变量命名,我copy一下文档,大概是这个样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 1字节的
bool bValue;
char cValue;
BYTE byValue;
// 2字节的
short sValue;
WORD wValue;
// 4字节的
BOOL bValue;
int iValue;
long lValue;
UINT uiValue;
DWORD dwValue;
float fValue;
// 8字节的
double dValue;
// 数组
char acValues[100];
UINT auiValues[100];
GePlayer akPlayers[100];
// 类实例(自定义的类)
GePlayer kPlayer;
// 枚举
GeState eState;
// 句柄
HANDLE hHandle;
// 成员变量
GePlayer m_kPlayer;
// 字符串
string kLenth;
U3D内部对象,能体现对象的含义即可
比如GameObject goObject; GameObject goUI;
RectTransform rectUI;

这个在JS里也是这么要求的(用前缀去命名一个c-union,2333),我以后估计代码风格就变成这个样子了。

规范

规范在大项目很重要,没有规范就没有一切,我能上手这个项目的很大原因就在于其清晰的结构和规范的命名(主要是协议命名)。很难相信梦2的代码是完全手撸的,我之前想参考梦2逻辑,问老大生成协议的xml,他告诉我没有xml,全部代码都是手撸的(当然包括每个通讯函数结构体的定义,及其读写方法)的时候,我一下子没反应过来。有句话说得好,前人栽树后人乘凉,我就是那个乘凉的人的其中一个,真的感谢前面种树的人,虽然很多都已经失联了,不过你们的留下的代码让我这个菜鸡学到了很多东西。

Contents
  1. 1. 运营
  2. 2.
  3. 3. 架构
  4. 4. 写的很怪的Node服务器
  5. 5. 规范