GS初始化
开启GameServer模式
init函数,现在看看这个大函数干什么的
//这个init也是GameServerUI里面调的,这个线程其实就做了一些初始化的工作,其实这里面没有什么主不主线程,都是在一个进程里面的
void __stdcall GameServer::init()
{
///设置最大连接数,现在还不知这个到底干啥的
Share::SetMaxGcNumb(); //指定本GS支持的最大数量 ///log日志,现在服务器写日志,在服务器报错的时候可以查看日志,还有报错时生成dump文件,然后上传ftp服务器,到时可以调试这个dump文件也可以知道在哪里报错
// Log记录,全局单例,支持多线程。
m_spLog = NEWSP(Log);
std::string strLogDir = safe::wcstombs(Plug::GetCurrentPath()) + "Log";
m_spLog->Init(strLogDir.c_str());
SetPlug("Log", m_spLog.get()); ///这个usbdog现在我不知道干啥的
I_USBDog* pDog = NEW(USBDog);
msg_assertex(pDog,"usb dog 创建失败!");
std::string str = (char*)Plug::GetApp()->m_app_shared;
if(str != "USBDog")
return ; ///主要是一些配置文件的拷贝,只要模板然后拷贝一份你可以配置
std::wstring wstrCurPath = Plug::GetCurrentPath();
CheckFileAndCopy(wstrCurPath + L"option.xml", wstrCurPath + L"option模板.xml");
CheckFileAndCopy(wstrCurPath + L"DBline.xml", wstrCurPath + L"DBline模板.xml");
CheckFileAndCopy(wstrCurPath + L"centerOption.xml", wstrCurPath + L"centerOption模板.xml"); ///在程序中开启控制打印,看变量的值
//#define ALLOC_CONSOLE
#ifdef ALLOC_CONSOLE
AllocConsole(); // 开辟控制台 释放:FreeConsole();
SetConsoleTitle(L"Debug Output"); // 设置控制台窗口标题
freopen("CONOUT$","w",stdout); // 重定向输出
printf("hello!\n");
#endif ////为进程指定CPU
//SetProcessAffinityMask(GetCurrentProcess(), 1L); ///连接中心服务器,天龙里面是世界服务器,我们这个可以说没啥用,天龙那个是架构的一部分,没咋看天龙那个世界服务器
/*连接centerServer*/
m_spCenterTcpLink = NEWSP(CenterTcpLink);
std::shared_ptr<I_SaveOption> spSaveOpt = NEWSP(SaveOption);
spSaveOpt->openFile((Plug::GetCurrentPath() + L"centerOption.xml").c_str());
std::string strIP = safe::wcstombs(spSaveOpt->getStr(L"root.ip"));
int nPort = spSaveOpt->getInt(L"root.port");
int nIP = ntohl(inet_addr(strIP.c_str()));
if (!m_spCenterTcpLink->Connect(nIP, nPort))
{
MessageBox(NULL, L"centerServer连接失败!", L"Error!", MB_ICONERROR);
::TerminateProcess(::GetCurrentProcess(), );
} //获取GameServer端口号
spSaveOpt->openFile((Plug::GetCurrentPath() + L"option.xml").c_str());
m_nPort = spSaveOpt->getInt(L"root.port"); /* 初始化数据库 */
m_spAsynDBC = NEWSP(asynDBCenter);///主要是mongo数据库的指针和加载任务等级信息,用于创建角色使用 spSaveOpt->openFile((Plug::GetCurrentPath() + L"DBline.xml").c_str());
std::string strDBIP = safe::wcstombs(spSaveOpt->getStr(L"root.ip"));
std::string strAcountDBName = safe::wcstombs(spSaveOpt->getStr(L"root.AccountDBName"));
std::string strActorDBName = safe::wcstombs(spSaveOpt->getStr(L"root.ActorDBName")); ///这个主要是数据库字段数组的初始化,这个数组的值就是对应到数据库里面的字段的,后面数据库的存取都用到这个数组,类似下面的形式
{//其中是根绝数组直接定位的
m_pConfigName[eAccountTable_INC] = "T_INC";
m_pConfigName[eAccountTable_User] = "T_UserInfo";
m_pConfigName[eServerTable_INC] = "T_INC";
m_pConfigName[eServerTable_Actor] = "T_ActorInfo";
m_pConfigName[eServerTable_Guild] = "T_GuildInfo";
m_pConfigName[eServerTable_Prop] = "T_PropInfo";
}
if(!m_spAsynDBC->Init(true))
{
MessageBoxA(GetTopWindow(NULL), "数据库初始化失败!", "Error!", MB_ICONERROR);
::TerminateProcess(GetCurrentProcess(), );
}
///这个登录过程主要是连接mongo和认证,然后就是保证一些表的存在,数据库现在主要分为账号数据库和角色数据库,这里用suerperamdmin登录,其他数据库也能使用了
if(!m_spAsynDBC->Login(strDBIP.c_str(), , ShuiHu::eServerDB_AoShiQianXiong, "SuperAdmin", ""))
{
MessageBoxA(GetTopWindow(NULL), "数据库连接失败!", "Error!", MB_ICONERROR);
::TerminateProcess(GetCurrentProcess(), );
}
///在ui上显示数据库线程id方便压测的
OnThreadId(m_spAsynDBC->GetThrID(), L"数据库"); ///对于长时间没有收到心跳包的客户端会被放入队列中,到时会释放,其实这个没咋看
I_TimerFactory* pTimeFactory = NEW(TimerFactory);
SetPlug("TimerFactory", pTimeFactory);
m_FreeQueueTimer.reset(pTimeFactory->createTimer());
m_FreeQueueTimer->regTimer(std::bind(&GameServer::FreeQueueTimer, this));
m_FreeQueueTimer->setInterval( * );//(30 * 1000);
m_FreeQueueTimer->start(); ///定时保存帮会信息,1min
m_SaveGuildInfoTimer.reset(pTimeFactory->createTimer());
m_SaveGuildInfoTimer->regTimer(std::bind(&DBSaveTiming::OnSaveGuildInfo, &m_DBSaveTiming));
m_SaveGuildInfoTimer->setInterval( * * ); ///定时保存道具信息,从道具管理器里面读取,然后保存到数据库,是整个服务器的道具定时存储
m_SavePropInfoTimer.reset(pTimeFactory->createTimer());
m_SavePropInfoTimer->regTimer(std::bind(&DBSaveTiming::OnSavePropInfo, &m_DBSaveTiming));
m_SavePropInfoTimer->setInterval( * * ); ///添加DataLayer单例好像gamemap里面也会用到,最后被废弃了,随后看看
m_spDataLayer = NEWSP(DataLayer);
add_singleton("DataLayer", m_spDataLayer.get());
//m_spDataLayer = NEWSP(GatwayData); ///网络初始化,就是双向的共享内存的初始化
if(!m_spDataLayer->Init())
{
Plug::PlugMessageBox(L"初始化网络失败!");
::TerminateProcess(::GetCurrentProcess(), );
} ShareInit(m_spDataLayer.get());
m_DBSaveTiming.SetAsynDBCPtr(m_spAsynDBC);
m_DBSaveTiming.SetPropMgrPtr(m_spPropManager);
m_DBSaveTiming.SetGuildOptPtr(m_spGuildOpt);
//获取帮会信息
m_fnGetGuildInfo = std::bind(&GameServer::ProcessGetGuildInfo, this, ph::_1, ph::_2);
m_spAsynDBC->GetGuildInfos(&m_fnGetGuildInfo);
//道具信息
m_funGetUserProp = std::bind(&GameServer::ProcessGetPropInfo, this, ph::_1, ph::_2);
m_spAsynDBC->GetPropInfos(&m_funGetUserProp); m_LiveMgr.m_fnTimeOutDisconnect = std::bind(&GameServer::TimeOutDisconnect, this, ph::_1);
m_LiveMgr.Init(GetMaxGcNumb()); m_vecChannel.resize(GetMaxGcNumb());
m_spThread.reset(new std::thread(std::bind(&GameServer::ProcessThread, this)));//创建一个线程,就是常说的GS线程,其实很多工作都是在这个线程里面做的
OnThreadId(m_spThread->get_id(), L"GS线程");
}
//可以看出主线程
void Share::ShareInit(I_DataLayer* data_layer)//share是管理所有地图信息的,非常重要
{
// 加载xls表
if(!LoadnBodyId())
Plug::PlugMessageBox("加载nBodyID表失败啊!");//三种职业,两种性别,nbodyid大概就代表地图资源
if(!LoadLevelInfo())
Plug::PlugMessageBox("加载角色等级信息失败!");//三种职业,71个等级的等级信息
if(!LoadMapData())
Plug::PlugMessageBox("加载地图数据失败!");//现在就有7张地图 /*地图数量*/ for(auto itMap : m_mapDataTable)
{
auto& pMap = m_mapMap[itMap.first] = NEW(Map);//m_mapMap是地图id对应一个地图指针信息
pMap->Init(GetMaxGcNumb(), itMap.second.map_path.c_str());//地图的初始化
pMap->m_fnGetLevelInfo = std::bind(&Share::TGetLevelInfo, this, ph::_1, ph::_2, ph::_3); pMap->m_nMapId = itMap.first;
std::wstring name = L"地图";
name += boost::lexical_cast<std::wstring>(pMap->m_nMapId);
OnThreadId(pMap->GetThreadId(), name); //获取线程ID
} m_pDataLayer = data_layer;
//初始化 跨地图操作模块
InitAcrossMapOpt();
InitAcrossManager();
} void Map::Init(int max_gc_numb, const char* res_path)
{
m_pLog = GetPlug(Log);//全局log单例
msg_assert(m_pLog); m_vecPlayerChannel.resize(max_gc_numb);//m_vecPlayerChannel代表了一个地图上的所有玩家 InitTimer();//map里面各种定时器的初始化
InitOpt();//主要是地图内的一些操作,帮会,组队,关系,交易,npc交互,将这给些给分开有利于模块的独立
InitMapInfoXml(res_path);//主要是地图的加载,块的划分,格子,2d人物通知都是用的格子,听说3d用的九宫格,只是听说
InitPropXml();//道具信息的读取
InitOrnamemtal();//这个不知干啥的
InitMonsterTypeInfoTable();//怪物信息记载
InitRegions();//区域的加载(安全区,战斗区)
InitSkillLevelInfoTable();//技能等级信息
InitMonsterDropRuleTable();//怪物掉落
InitPlayerDropRuleTable();//人物掉落
InitPetArrributeTable();//宠物属性
InitSkillRestrictInfoTable();//限制技能读取 InitSkillScript();//技能脚本
InitMission();//任务
InitMgr();//管理加载 Start();//map线程启动
}
GS初始化的更多相关文章
- GS LiveMgr心跳管理类
struct LiveMgr { private: int m_nCount; ///< 管理数量 std::vector<int> m_vecChannels; ///< 所 ...
- MongoDB学习笔记~数据模型属性为集合时应该为它初始化
回到目录 今天要说一下技术点,我们在设计mongodb的数据模型时,如果属性是数组或者集合类型,我们在模型初始化时,需要为它们初始化一下,否则在数据库里将会被存储为NULL,当被存储为NULL时,我们 ...
- 关闭GS选项,解决注入后崩溃
利用CreateRemoteThread向进程注入远程代码时,一般会有以下两种做法: 利用LoadLibrary在目标进程加载指定的DLL 将代码复制到目标进程,然后启动这段代码 上面的第二种方法其实 ...
- 中断——中断描述符表的定义和初始化(一) (基于3.16-rc4)
1.中断描述符表的定义(arch/x86/kernel/traps.c) gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss; 定义的描述 ...
- OD: Windows Security Techniques & GS Bypassing via C++ Virtual Function
Windows 安全机制 漏洞的万源之本在于冯诺依曼设计的计算机模型没有将代码和数据进行区分——病毒.加壳脱壳.shellcode.跨站脚本攻击.SQL注入等都是因为计算机把数据和代码混淆这一天然缺陷 ...
- 20155306 白皎 0day漏洞——漏洞利用原理之GS
20155306 白皎 0day漏洞--漏洞利用原理之GS 一.GS安全编译选项的保护原理 1.1 GS的提出 在第二篇博客(栈溢出利用)中,我们可以通过覆盖函数的返回地址来进行攻击,面对这个重灾区, ...
- WebApi 插件式构建方案:IOC 容器初始化
body { border: 1px solid #ddd; outline: 1300px solid #fff; margin: 16px auto; } body .markdown-body ...
- 内存保护机制及绕过方案——通过覆盖虚函数表绕过/GS机制
1 GS内存保护机制 1.1 GS工作原理 栈中的守护天使--GS,亦称作Stack Canary / Cookie,从VS2003起开始启用(也就说,GS机制是由编译器决定的,跟操作系统 ...
- GS与MS之间通信
GS与MS之间通信 注意GS与MS是两个线程,现在是每个map一个线程,他们之间是内部协议进行通信的,那既然是两个线程那如何通信呢,看了net进程通信这个就比较简单了 举个例子 m_pMap-> ...
随机推荐
- MHA学习笔记
MHA是一款开源的MySQL高可用程序,为MySQL主从复制架构提供了节点故障转移功能,当 master发生故障时MHA会自动提升拥有最新数据的slave节点成为新的主节点,还提供了master节 点 ...
- linux 下su 和sudo 的用法以及区别
一. 使用 su 命令临时切换用户身份 1.su 的适用条件和威力 su命令就是切换用户的工具,怎么理解呢?比如我们以普通用户beinan登录的,但要添加用户任务,执行useradd ,beinan用 ...
- 通过API函数来控制SQLite数据库增删改查
person类属性有Intenger id,String name,Intenger age,相应的构造方法和set get方法. package com.xh.tx.dao; import and ...
- C++primer 阅读点滴记录(二)
智能指针(smart point) 除了增加功能外,其行为像普通指针一样. 一般通过使用计数(use count)或引用计数(reference count)实现智能指针,防止出现指针 ...
- STM32F4_USART配置及细节描述
Ⅰ.概述 关于USART串口通信,可以说是MCU的标配.不管是在实际项目应用中,还是在开发过程中,它都起着很重要的作用. 在项目应用中我们常常使用UART串口进行通信,根据通信的距离及稳定性,还选择添 ...
- matlab封装DLL混合编程总结
最近做了个项目要用到matlab做些算法处理,然后用.net项目调用这个类,我把这个matlab封装dll总结了下如下: matlab是商业数学软件,优势是在算法开发上面有很强的功能,提供了很多数学算 ...
- 使用Telerik控件搭建Doubanfm频道部分
今天感觉好累啊..还是坚持记录下. 收集的API: https://github.com/HakurouKen/douban.fm-api https://github.com/zonyitoo/do ...
- C基础 数据序列化简单使用和讨论
前言 C中对序列化讨论少, 因为很多传输的内容都有自己解析的轮子. 对于序列化本质是统一编码, 统一解码的方式. 本文探讨是一种简单的序列化方案. 保证不同使用端都能解析出正确结果. 在文章一开始, ...
- hdu 1867 A + B for you again
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1867 A + B for you again Description Generally speaki ...
- JVM学习总结一——内存模型
JVM是java知识体系的基石之一,任何一个java程序的运行,都要借助于他.或许对于我这种初级程序员而言,工作中很少有必要刻意去关注JVM,然而如果能对这块知识有所了解,就能够更清晰的明白程序的运行 ...