我是靠谱客的博主 沉默灯泡,这篇文章主要介绍mangos0.9代码分析(一),现在分享给大家,希望可以做个参考。

最近下到了一份mangos0.9版本的源码,打算用心读一读,也算是学习学习。

当然这也是本人第一次接触游戏服务器源码,估计会遇到很多很多的问题,这篇文章也是本人的第一篇博客,来csdn那么多年了,终于打算开始写点东西了,接下来的一段时间,想自己研究研究这份代码,随手写点东西也算是做了笔记了。

        mangos不是一个魔兽私服模拟器,它是一个开源的自由软件项目,是用c++和C#编程语言,实现的一个支持大型多人在线角色扮演游戏服务器的程序框架,在这个框架下,它理论上应该支持任何客户端的网络游戏,由于现在很多人使用魔兽世界来对它进行测试,所以针对魔兽世界的脚本和数据库文件比较完善,很多人就利用这个开源项目来实现魔兽私服。mangos的技术细节上是这样的,核心部分是个和特定游戏没有关系的核心框架程序,主要是进行进程调度,创造世界,建立心跳机制,处理网络接入等。数据库也是使用的开源数据库软件MySQL,编译器使用的是GCC。至于游戏内容数据库,游戏人物,时间,世界脚本,都是由这个核心程序所支持的扩展脚本来实现,所以有一些独立出来的项目专门模拟魔兽世界来开发支持mangos的核心程序。现在mangos的核心程序已经放到著名的协同开发网站sourceforge上开发了,使用的版本控制工具是subversion,(目前已经迁移到GIT)。大家都可以到github下载最新的源代码程序。(该段转自百度百科)

     我下载的mangos0.9版本在csdn资源中就有,源代码在mangos/src目录中,该目录中包括6个文件夹,和makefile.in 和makefile.am文件,这两个文件不用说的,产生makefile文件用的。 关键在所包含的六个文件夹  bindings   framework  game  mangosd  realmd  shared 。

其中bindings文件夹中包含脚本文件,应该是对脚本进行绑定的。

framework文件夹中包括一些游戏框架,其中包括网络框架,游戏系统框架,工具,平台等内容。

game文件夹中应该是游戏的文件,包括世界系统,战斗系统,游戏事件,游戏场景等的实现。

mangosd文件夹中是mangosd的主程序,包括程序的入口等。

realmd 文件夹中是游戏区域信息,包括RealmList等内容。

shared文件夹中 应该是公用的函数和库,database的内容包含在其中。

以上内容只是自己的摸索,不保准的,呵呵。

另外分析一下整体结构:

mangos使用了4个外部工具库,分别是:

       跨平台的网络通讯框架The ADAPTIVE Communication Environment (ACE)
  压缩库zlib
  Socket通信库 C++ Sockets Library  和  C++的并行编程模板库Threading Building Blocks (tbb 和 tbbmalloc)


mangos可以分为以下几个工程模块:

      工程mangosd 

      mangos是世界服务器的管理器,负责初始化工作和启动世界服务器各层的线程,这些工作主要是由类Master来实现。

      类Master执行包括连接数据库,载入世界模型,启动世界更新线程,启动命令行线程,启动RA线程等操作。

      mangosd共有13个线程:

       一个World线程(逻辑层)
    三个DB线程(数据层)
  一个CLI线程(输入层),运行时候会生成一个WorldDatabase线程
  一个RA线程(管理层)
  一个freeze catcher 线程(可选)
  工程g3dlite:游戏逻辑层的底层库
  工程framework:系统框架
  工程realm :负责登陆和选择游戏服务器,进行负载均衡用到了C++ Sockets Library进行登录处理,采用select I/O模型实现了Wow, Mangos登录时的SRP6认证客户端作为它的client连接到realm server认证和选择了mangos server就断开 而mangos server和realm server则不进行连接,只是通过数据库交互数据:mangos server把自己的状态和拥有的角色数放入库中realm server会读取数据库中的这些信息来获知mangos server的状态 数据库realm的realmlist表保存了realm的列表。

      工程game
  game:是Mangos的核心代码,网络层和逻辑层代码(采用了ACE反应器(Reactor)模式)    

     mangos的执行模型如下:   

一、线程分布:
1、主线程 main---- Master::Run() ,主要功能:初始化world、创建子线程、回收资源
2、WorldRunnable -------GS主线程
3、CliRunnable -----后台调试线程
4、RARunnable -------事件处理和分发线程
5、MaNGOSsoapRunnable---协议
6、FreezeDetectorRunnable
7、线程池  Master::Run----WorldSocketMgr::StartNetwork---WorldSocketMgr::StartReactiveIO ---ReactorRunnable

二、事件分发和处理
WorldRunnable::run---World:update----World:UpdateSessions---WorldSession::Update(一个socket内所有事件)---各种各样的handler

基本框架:ACE的Reactor机制(ACE_TP_Reactor)

三、WorldRunnable 主要功能
WorldRunnable ----World 定时器任务+网络事件(session中的)+异步IO回调+任务系统调度+cli

 

     以上部分内容参考网络上一些资料  
     

按照逻辑,先从mangosd开始读起, 因为目前我也不是很清楚这份代码的架构,也处于摸索阶段,先从main开始入手,也算是摸着石头过河了。

复制代码
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// 此处略去了版权声明,开源软件尊重版权 #include "Common.h" #include "Database/DatabaseEnv.h" #include "Config/ConfigEnv.h" #include "Log.h" #include "Master.h" #include "SystemConfig.h" // 用于系统的判断,用于兼容Windows系统,mangosd原本是linux下的开源软件 #ifdef WIN32 #include "ServiceWin32.h" char serviceName[] = "mangosd"; char serviceLongName[] = "MaNGOS world service"; char serviceDescription[] = "Massive Network Game Object Server"; /* * -1 - not in service mode * 0 - stopped * 1 - running * 2 - paused */ int m_ServiceStatus = -1; #endif //选择数据库的宏定义,一般选择MySql数据库 ,其中DatabaseMySql类定义在shared文件夹中,数据库类作为公共文件 #ifdef DO_POSTGRESQL DatabasePostgre WorldDatabase; ///< Accessor to the world database DatabasePostgre CharacterDatabase; ///< Accessor to the character database DatabasePostgre loginDatabase; ///< Accessor to the realm/login database #else DatabaseMysql WorldDatabase; ///< Accessor to the world database DatabaseMysql CharacterDatabase; ///< Accessor to the character database DatabaseMysql loginDatabase; ///< Accessor to the realm/login database #endif uint32 realmID; /// 使用一个全局变量记录游戏区域的id,因为游戏区id唯一性,一旦选择应该保持全局不变 /// 从终端输出一些版本Server运行信息 void usage(const char *prog) { sLog.outString("Usage: n %s [<options>]n" " -c config_file use config_file as configuration filenr" #ifdef WIN32 " Running as service functions:nr" " --service run as servicenr" " -s install install servicenr" " -s uninstall uninstall servicenr" #endif ,prog); } /// 主函数,登录mangos的入口 extern int main(int argc, char **argv) { // 创建一个mangos内存管理 并对该内存管理类进行初始化 // 该内存管理类模版在framework文件中的policies中进行声明,使用MaNGOS命名空间,负责什么以后再看了。。。 MaNGOS::Singleton<MemoryManager>::Instance(); ///读取Mangosd的配置文件 其中 宏_MANGOSD_CONFIG为"mangosd.conf" 该配置文件就在mangosd文件夹中 char const* cfg_file = _MANGOSD_CONFIG; int c=1; //下面执行的是一些附带命令,在启动时作为附带命令来指定文件和输出相关信息 ( 附带命令是随便解释的呵呵 ) while( c < argc ) { if( strcmp(argv[c],"-c") == 0) { // "-c"应该是配置文件的命令,后面附带配置文件 if( ++c >= argc ) { // 后文不带参数,报错 sLog.outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; // 配置文件 } // 以下宏定义范围内为Windows下的文件配置信息也是用来配置configure文件的, 此处略过 #ifdef WIN32 //Services// if( strcmp(argv[c],"-s") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if( strcmp(argv[c],"install") == 0) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if( strcmp(argv[c],"uninstall") == 0) { if(WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else { sLog.outError("Runtime-Error: unsupported option %s",argv[c]); usage(argv[0]); return 1; } } if( strcmp(argv[c],"--service") == 0) { WinServiceRun(); } #endif ++c; } // 读取配置文件出错 if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); return 1; } // 成功读取配置文件,输出信息 sLog.outString("Using configuration file %s.", cfg_file); // 其实服务器主程序应该是在这里运行的,这个sMaster对象这样定义着 // #define sMaster MaNGOS::Singleton<Master>::Instance() // 其实还是作为Singleton的模版传进去进行初始化后得到的,这里的Singleton是不是设计模式中的单例模式呢??我也不清 // 楚 呵呵 // 而模版类MaNGOS::Singleton<Class T ,..., ...> 自我感觉应该是非常关键的一点,以后会详细分析其实现和设计 sMaster.Run(); // 运行Master对象 ,至此,Mangos开始运行。 return 0; }

其实 mangos中的main()多是一些配置文件信息,进行数据库,内存管理,配置文件的初始化等工作,然后执行sMaster开始真正运行系统。

下一次顺着这条路 从sMaster开始接着向下分析。

实验室关门了。。

 

复制代码
1

最后

以上就是沉默灯泡最近收集整理的关于mangos0.9代码分析(一)的全部内容,更多相关mangos0内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部