一、服务器构架
一个天龙八部游戏区,主要服务器部署情况如下图所示:
实际部署可能有所不同。区角色数据库可以安装到Machine4,那么一个区有5台物理机器。LoginServer和WorldServer、CharacterDB、BillingServer有连接。WorldServer和各个GameServer有连接。ShareMemory和CharacterDB有连接。
一台物理机器上,会启动一个ShareMemory进程和一个服务器进程,服务器进程有世界服务器和游戏服务器。天龙八部的世界是ZoneBase的,一个游戏服务器服务启动多个线程,每个线程服务若干个场景。
在ShareMemory进程、WorldServer和GameServer进程,都需要对多种共享内存池进行初始化,初始化传入的类型是不同的,类型定义如下:
enum SMPOOL_TYPE
{
SMPT_SHAREMEM,
SMPT_SERVER,
SMPT_WORLD
};
共享内存池对象在ShareMemory进程中初始化时候,才会真正分配共享内存对象,并把池对象Attach到共享内存对象。在WorldServer和GameServer进程中,池对象只是获取共享内存对象并Attach。
天龙八部使用的共享内存对象有:
角色 SMUPool<HumanSMU> 类型ST_HUMAN_SMU;
公会 SMUPool<GuildSMU> 类型ST_GUILD_SMU;
邮件 SMUPool<MailSMU> 类型ST_MAIL_SMU;
玩家商店 SMUPool<PlayerShopSM> 类型ST_PSHOP_SMU;
道具序列号SMUPool<ItemSerialKeySMU> 类型ST_ITEMSERIAL_SMU;
二、共享内存模块
几个关键的类和结构定义如下图:
ShareMemAO封装了系统共享内存API功能,提供了池对象Attach/Detach接口以及转储文件功能。
SMUPool模板类是具体的池对象,天龙八部实现的池类型有5种,具体数据类型对应5个结构:HumanSMU、GuildSMU、MailSMU、PlayerShopSM和ItemSerialKeySMU。
SMULogicManager模板类提供了对这些共享内存池对象进行管理的功能,如初始化、心跳、保存数据库、清理等操作。
三、ShareMemory进程中共享内存模块的主要功能
具体见ShareMemory.h/ShareMemory.cpp,该服务进程主要功能是:
l 根据配置创建共享内存池对象(SMUPool)和池管理对象(SMULogicManager);
l 对创建的内存池对象和池管理对象进行初始化,注意初始化传入的类型是SMPT_SHAREMEM;如果是这个类型,底层会分配具体的共享内存,而不是仅仅的Attach;
l 对共享内存池管理对象进行更新(心跳),会进行数据库存储等操作,这里是保存数据库的唯一地方。那么数据从数据库的加载是在哪里?下面会介绍,是在LonginServer进程里面。
关于数据库模块,顺带提一下,从代码看天龙居然用的还是ODBC接口,后来应该改了吧。
四、WorldServer中的共享内存池对象
具体见ShareMemManager.h/ShareMemManager.cpp。WorldServer中仅对两类池对象进行操作,他们是GuildSMU和MailSMU。
extern SMUPool<GuildSMU> g_GuildSMUPool;
extern SMUManager<GuildSMU> g_GuildSMUManager;
extern SMUPool<MailSMU> g_MailSMUPool;
extern SMUManager<MailSMU> g_MailSMUManager;
两个共享内存池对象的初始化在World.cpp的BOOL World::NewStaticManager( )函数中,注意此处传入的类型是SMPT_WORLD。
五、GameServer中的共享内存池对象
具体见ShareMemManager.h/ShareMemManager.cpp。GameServer中对三类池对象进行操作,他们是HumanSMU、PlayerShopSM和ItemSerialKeySMU。
SMUPool<HumanSMU> g_HumanSMUPool;
SMUPool<PlayerShopSM> g_PlayerShopSMUPool;
SMUPool<ItemSerialKeySMU> g_ItemSerialSMUPool;
这些共享内存池对象的初始化在Server.cpp的BOOL Server::NewStaticManager( )函数中,注意此处传入的类型是SMPT_SERVER。