zoukankan      html  css  js  c++  java
  • GS初始化

    开启GameServer模式
    init函数,现在看看这个大函数干什么的
    //这个init也是GameServerUI里面调的,这个线程其实就做了一些初始化的工作,其实这里面没有什么主不主线程,都是在一个进程里面的
    void __stdcall GameServer::init()
    {
        ///设置最大连接数,现在还不知这个到底干啥的
        Share::SetMaxGcNumb(12000); //指定本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!
    ");
    #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(), 0);
        }
    
        //获取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(), 0);
        }
        ///这个登录过程主要是连接mongo和认证,然后就是保证一些表的存在,数据库现在主要分为账号数据库和角色数据库,这里用suerperamdmin登录,其他数据库也能使用了
        if(!m_spAsynDBC->Login(strDBIP.c_str(), 27017, ShuiHu::eServerDB_AoShiQianXiong, "SuperAdmin", "123456"))
        {
            MessageBoxA(GetTopWindow(NULL), "数据库连接失败!", "Error!", MB_ICONERROR);
            ::TerminateProcess(GetCurrentProcess(), 0);
        }
        ///在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);//(30 * 1000);
        m_FreeQueueTimer->start();
        
        ///定时保存帮会信息,1min
        m_SaveGuildInfoTimer.reset(pTimeFactory->createTimer());
        m_SaveGuildInfoTimer->regTimer(std::bind(&DBSaveTiming::OnSaveGuildInfo, &m_DBSaveTiming));
        m_SaveGuildInfoTimer->setInterval(1 * 60 * 1000);
    
        ///定时保存道具信息,从道具管理器里面读取,然后保存到数据库,是整个服务器的道具定时存储
        m_SavePropInfoTimer.reset(pTimeFactory->createTimer());
        m_SavePropInfoTimer->regTimer(std::bind(&DBSaveTiming::OnSavePropInfo, &m_DBSaveTiming));
        m_SavePropInfoTimer->setInterval(1 * 60 * 1000);
    
        ///添加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(), 0);
        }
    
        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线程启动
    }
  • 相关阅读:
    HOJ 2139 Spiderman's workout(动态规划)
    FZU 2107 Hua Rong Dao(dfs)
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 无向连通图最少包含多少条边
    Java 第十一届 蓝桥杯 省模拟赛 无向连通图最少包含多少条边
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4107111.html
Copyright © 2011-2022 走看看