Files
mir_server/server/LogicServer/LogicServer.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

702 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "LogicServer.h"
#include "base/Container.hpp"
CLogicEngine* CLogicServer::s_pLogicEngine =NULL;
CLogicServer::CLogicServer()
{
GameServerEntry::g_pLogicServer = this;
s_pLogicEngine = NULL;
m_pDBClient = NULL;
m_sServerName[0] = 0;
m_nServerIndex =0;
m_boStarted = FALSE;
m_boStopServ = FALSE;
m_bCommonServer = false;
m_nCommonServerId = -1;
m_szCommonLoginSrvIP[0] = '\0';
m_szCommonDbSrvIp[0] = '\0';
m_nCommonDbSrvPort = 0;
m_minCommonPort = 0;
m_maxCommonPort = 0;
InitStaticVar();
m_pDataProvider = new CLogicDataProvider();
//创建网关管理器
m_pGateManager = new CLogicGateManager(this);
m_pGateManager->Initialize();
// 创建公共服务器Server端
//创建会话客户端
m_pSSClient = new CLogicSSClient(this);
m_pDataConfig = new CLogicServerConfig;
//创建数据客户端
m_pDBClient = new CDataClient(this);
//日志客户端 在外部创建
m_pLogClient = new LogSender();
//公共日志客户端
m_pLocalClient = new CLocalSender();
//创建逻辑引擎
s_pLogicEngine = new CLogicEngine();
m_pDataProvider->SetLogicEngine(s_pLogicEngine);
m_pBackClient = new CBackStageSender();
m_pCommonClient = new CCommonClient();
m_pCrossServer = new CCrossServerManager();
m_pCrossClient = new CLocalCrossClient();
m_pAsyncWorker = new AsyncWorker(_T("./data/functions/AsyncWorkerFunction.txt"));
m_pAsyncWorker->SetWorkCallBack(&CLogicEngine::PostAsyncWorkMsg);
m_boStartCommonServer = true;
m_CreateIndex = 0;
m_bChangeNameFlag = true;
m_bQuestSaveLog = true;
m_bCoinSaveLog = true;
m_bCrossServer = false;
}
VOID CLogicServer::SetCommonServerAddr(LPCSTR sLoginSrvIp,LPCSTR sDbSrvIp, int nPort,int nMinPort,int nMaxPort)
{
_asncpyt(m_szCommonLoginSrvIP, sLoginSrvIp);
_asncpyt(m_szCommonDbSrvIp , sDbSrvIp);
m_nCommonDbSrvPort = nPort;
m_minCommonPort = nMinPort;
m_maxCommonPort = nMaxPort;
if (m_bCommonServer)
{
OutputMsg(rmTip,"is common server common db server ip=%s,port=%d,loginip=%s,login server minport=%d,maxprot=%d",sDbSrvIp,nPort,sLoginSrvIp,nMinPort,nMaxPort);
//m_pCommonServer->SetServiceHost(sDbSrvIp);
//m_pCommonServer->SetServicePort(nPort);
//m_pCommonServer->SetMinServerPort(wMinPort);
//m_pCommonServer->SetMaxServerPort(wMaxPort);
}
else
{
OutputMsg(rmTip,"Not common server common db server ip=%s,port=%d,loginip=%s,login server minport=%d,maxprot=%d",sDbSrvIp,nPort,sLoginSrvIp,nMinPort,nMaxPort);
m_pCommonClient->SetServerHost(sDbSrvIp);
m_pCommonClient->SetServerPort(nPort);
//m_pCommonClient->SetMinServerPort(wMinPort);
//m_pCommonClient->SetMaxServerPort(wMaxPort);
}
}
CLogicServer::~CLogicServer()
{
//停止服务
StopServer();
#ifdef _USE_TRY_CATCH
#ifdef WIN32
__try
#endif
#endif
{
//按反向关联顺序销毁对象
//SafeDelete(m_pFrdClient);
//SafeDelete(m_pMgrClient);
//SafeDelete(m_pCommonServer);
SafeDelete(m_pBackClient);
SafeDelete(m_pCommonClient);
SafeDelete(m_pSSClient);
SafeDelete(s_pLogicEngine);
SafeDelete(m_pDBClient);
SafeDelete(m_pLogClient);
SafeDelete(m_pLocalClient);
SafeDelete(m_pCrossClient);//
SafeDelete(m_pCrossServer);//
m_pGateManager->Uninitialize();
SafeDelete(m_pGateManager);
SafeDelete(m_pDataProvider);
SafeDelete(m_pDataConfig);
SafeDelete(CRankingMgr::m_pAllocator);
SafeDelete(CEnvirConfig::m_pAllocator);
SafeDelete(CObserverSystem::s_seqVisibleList);
SafeDelete(CObserverSystem::s_OBEntityList);
SafeDelete(m_pAsyncWorker);
ReleaseStaticVar();
}
#ifdef _USE_TRY_CATCH
#ifdef WIN32
__except(CustomExceptHandler(GetExceptionInformation()))
{
}
#endif
#endif
}
VOID CLogicServer::SetServerName(LPCSTR sName)
{
sprintf_s(m_sServerName, ArrayCount(m_sServerName), "%s-V%s-[%d]", sName,CLogicServer::GetLogicVersion(),GetCurrentProcessId());
SetConsoleTitle(m_sServerName);
}
//做全局变量的初始化工作
VOID CLogicServer::InitStaticVar()
{
CFuBenManager::m_SceneMgr = new SceneHandleMgr(_T("SceneHdlMgr"));
CFuBenManager::m_FuBenMgr = new CFuBenHandleMgr(_T("FubenHdlMgr"));
//CEntityGrid::g_EntityListMgr = new CEntityListMgr(_T("EntityListHdlMgr"));
CFuBenManager::m_pVisibleList = new EntityVector();
CAggressorAI::s_pVisibleEntityList = new EntityVector();
CAggressorAI::s_pVisibleEntityList->reserve(100);
//CEntityList::g_LinkNodeMgr = new CEntityList::LinkNodeMgr(_T("EntityLinkNodeHdlMgr"));
//RepeatList::g_LinkNodeMgr = new RepeatList::LinkNodeMgr(_T("RepeatLinkNodeHdlMgr"));
//ActorNodeList::g_LinkNodeMgr = new ActorNodeList::LinkNodeMgr(_T("ActorNodeHdlMgr"));
CObserverSystem::s_seqVisibleList = new EntityVector();
CObserverSystem::s_seqVisibleList->reserve(250);
CObserverSystem::s_OBEntityList = new CVector<EntityHandleTag>();
CObserverSystem::s_OBEntityList->reserve(250);
CActor::s_itemDropPtrList = new CVector<CUserItem*>;
CActor::s_itemDropTypeList = new CVector<BYTE>;
//CObserverEntityList::g_LinkNodeMgr = new CObserverEntityList::LinkNodeMgr(_T("ObserverNodeHdlMgr"));
CBuffSystem::m_pAllocator = new CSingleObjectAllocator<CDynamicBuff>(_T("CDynamicBuff"));
CMovementSystem::s_pAStar = new(CAdvanceAstar);
//CGuild::GuildInterMsgList::g_LinkNodeMgr = new CGuild::GuildInterMsgList::LinkNodeMgr(_T("GuildInterMsgNodeHdlMgr"));
//FubenHandleList::g_LinkNodeMgr = new FubenHandleList::LinkNodeMgr(_T("FubenLinkNodeHdlMgr"));
CActor::MessageBoxList = new CVector<MessageBoxItem>();
CRankingMgr::m_pAllocator = new CBufferAllocator();
CEnvirConfig::m_pAllocator = new CBufferAllocator();
CActorDataPacketStatAlloc::m_spADPSAllocator = new CActorDataPacketStatAlloc();
CAnimal::InitStateForbidMask();
GlobalObjectMgr::initialize();
CBoxDropMgr::initialize();
CLogicLuaAllocator::InitializeAllocator();
}
//释放程序中的全局变量
VOID CLogicServer::ReleaseStaticVar()
{
SafeDelete(CFuBenManager::m_SceneMgr);
SafeDelete(CFuBenManager::m_FuBenMgr);
//SafeDelete(CEntityGrid::g_EntityListMgr);
SafeDelete(CFuBenManager::m_pVisibleList);
SafeDelete(CAggressorAI::s_pVisibleEntityList);
//SafeDelete(CEntityList::g_LinkNodeMgr);
//SafeDelete(RepeatList::g_LinkNodeMgr);
//SafeDelete(ActorNodeList::g_LinkNodeMgr);
//SafeDelete(CObserverEntityList::g_LinkNodeMgr);
SafeDelete(CBuffSystem::m_pAllocator);
SafeDelete(CMovementSystem::s_pAStar);
//SafeDelete(CGuild::GuildInterMsgList::g_LinkNodeMgr);
//SafeDelete(FubenHandleList::g_LinkNodeMgr);
SafeDelete(CActor::MessageBoxList);
SafeDelete(CActorDataPacketStatAlloc::m_spADPSAllocator);
if(CActor::s_itemDropPtrList)
{
CActor::s_itemDropPtrList->empty();
SafeDelete(CActor::s_itemDropPtrList);
}
if(CActor::s_itemDropTypeList)
{
CActor::s_itemDropTypeList->empty();
SafeDelete(CActor::s_itemDropTypeList);
}
CAnimal::DestroyStateForbidMask(); //释放
CBoxDropMgr::release();
GlobalObjectMgr::uninitialize();
CLogicLuaAllocator::UninitializeAllocator();
}
VOID CLogicServer::SetLogClient( LogSender * pLogClient )
{
if(m_pLogClient == NULL)
{
m_pLogClient = pLogClient;
}
else
{
SafeDelete(pLogClient);
}
}
#define START_SERVER_CLIENT
BOOL CLogicServer::StartServer()
{
//初始化网络库
if ( CLogicGateManager::InitSocketLib() )
{
OutputError(GetLastError(), _T("initialize inet library failure"));
return FALSE;
}
m_boStarted = TRUE;
m_boStopServ = TRUE;
if ( !m_pVSPDefines.LoadDefinitions(_T("data/VSPDef.txt")) )
{
return FALSE;
}
if ( !m_LanguageText.LoadFromFile(_T("data/language/LangCode.config")))
{
return FALSE;
}
if ( !m_LanguageText.LoadFromFile(_T("data/language/LangCode.txt")))
{
return FALSE;
}
winitseed(0); //初始化随机数
if (!m_pDataProvider->LoadConfig() )
{
return FALSE;
}
//加载运行时数据,允许加载失败
m_pDataProvider->LoadRunTimeData();
#ifdef START_SERVER_CLIENT
//启动DBlient
if (m_pDBClient )
{
if (!m_pDBClient->Startup())
{
return FALSE;
}
}
//启动会话管理器
if(m_pSSClient)
{
if(!m_pSSClient->Startup())
{
return FALSE;
}
}
//启动网关管理器
if ( !m_pGateManager->Startup() )
return FALSE;
//启动logclient
if (m_pLogClient)
{
LPCTSTR sSpid = GetVSPDefine().GetDefinition("SPID");
m_pLogClient->SetServerSpid(sSpid);
if (!m_pLogClient->Startup())
{
return FALSE;
}
}
//启动公共日志服务器
if(m_pLocalClient)
{
if(!m_pLocalClient->Startup())
{
return FALSE;
}
}
//启动好友客户端
//m_pFrdClient->SetServerName(m_sServerName);
//m_pFrdClient->SetServerIndex(m_nServerIndex);
//if (!m_pFrdClient->Startup())
// return FALSE;
//m_pMgrClient->SetServerName(m_sServerName);
//m_pMgrClient->SetServerIndex(m_nServerIndex);
//m_pMgrClient->SetSpId(m_nSpID);
//if (!m_pMgrClient->Startup())
//return FALSE;
if (m_pBackClient != NULL)
{
if(!m_pBackClient->Startup())
return FALSE;
}
#endif
// 逻辑服务器之间的连接监听
if (strlen(m_szCommonDbSrvIp) > 0 && m_nCommonDbSrvPort > 0)
{
if (m_bCommonServer)
{
//if (!m_pCommonServer->Startup())
// return FALSE;
}
else
{
if (!m_pCommonClient->Startup())
return FALSE;
}
}
//跨服
if(m_bCrossServer) {
if ( !m_pCrossServer->Startup() ) {
return false;
}
}
//跨服
if ( m_nCrossServerId //ID有效
&& !IsCrossServer()) //不是原服不需要启动
{
if ( !m_pCrossClient->Startup() ) {
return false;
}
}
//最后启动逻辑管理器
s_pLogicEngine->StartEngine();
//启动异步线程
m_pAsyncWorker->StartWorkThread();
OnStartedServer();
return TRUE;
}
char *CLogicServer::GetLogicVersion()
{
in_addr ia;
ia.s_addr = LOGIC_KN_VERSION;
return inet_ntoa(ia);
}
VOID CLogicServer::StopServer(bool bSaveFile)
{
if (!m_boStarted)
return;
// if(m_pCrossServer)
// {
// OutputMsg(rmTip, "Stop CrossServer!");
// m_pCrossServer->Stop();
// }
//停止异步线程
m_pAsyncWorker->StopWorkThread();
//停止网关管理器
m_pGateManager->Stop();
//等待并停止逻辑引擎
s_pLogicEngine->StopEngine();
//m_pMgrClient->Stop();
//等待并停止好友客户端
//m_pFrdClient->Stop();
m_pBackClient->Stop();
//等待并停止会话客户端
if(m_pSSClient)
{
m_pSSClient->Stop();
}
if(m_pCrossClient)
{
OutputMsg(rmTip, "Stop1 CrossClient!");
m_pCrossClient->Stop();
OutputMsg(rmTip, "Stop2 CrossClient!");
}
//等待并停止日志客户端
if(m_pLogClient)
{
m_pLogClient->Stop();
}
//等待并停止公共日志服务器
if(m_pLocalClient)
{
OutputMsg(rmTip, "Stop1 LocalClient!");
m_pLocalClient->Stop();
OutputMsg(rmTip, "Stop2 LocalClient!");
}
//等待并停止数据客户端
if (m_pDBClient )
{
OutputMsg(rmTip, "Stop1 DBClient!");
m_pDBClient->WaitFor();
m_pDBClient->Stop();
OutputMsg(rmTip, "Stop2 DBClient!");
}
//保存运行时数据,允许保存失败
m_pDataProvider->SaveRunTimeData();
if(bSaveFile)
{
GetGlobalLogicEngine()->DumpDataAllocator();
DebugBreak();
}
//卸载网络库
CLogicGateManager::UnintSocketLib();
m_boStarted = FALSE;
m_boStopServ = FALSE;
}
//获取当前时间是开服以来的第几天0表示还没到开服时间1表示开服当天2表示开服的第2天比如1号1开服2号返回2
int CLogicServer::GetDaysSinceOpenServer()
{
//这里首先判断是开服以来的第几天
CMiniDateTime nCurrentTime = CMiniDateTime::now();
CMiniDateTime openServerTime = GetServerOpenTime(); //获取开服的时间
if(nCurrentTime.tv < openServerTime.today()) //还没到开服时间
{
return 0;
}
else
{
unsigned int nTomorrow = CMiniDateTime::tomorrow(); //明天早上凌晨的时间
int nSec = ( int)(nTomorrow - openServerTime);
return (int)(nSec / (3600 * 24)) +1; //中间间隔了多少天
}
}
//判断当前开服天数是否满足
bool CLogicServer::CheckOpenServer(int nDay)
{
return GetDaysSinceOpenServer() >= nDay?true:false;
}
int CLogicServer::GetDaysSinceCombineServer()
{
CMiniDateTime nCurrentTime = CMiniDateTime::now();
CMiniDateTime combineServerTime = GetServerCombineTime(); //获取合服的时间
if(nCurrentTime.tv < combineServerTime.tv || combineServerTime.tv <= 0) //还没到合服时间
{
return 0;
}
else
{
unsigned int nTomorrow = CMiniDateTime::tomorrow(); //明天早上凌晨的时间
int nSec = ( int)(nTomorrow - combineServerTime);
return (int)(nSec / (3600 * 24)) +1; //中间间隔了多少天
}
}
void CLogicServer::SetStartCommonServer(bool flag)
{
if (IsCommonServer()) return;
if(m_boStartCommonServer == flag) return; //如果 已经是相等了,则不处理
m_boStartCommonServer = flag;
char data[512];
CDataPacket pack(data,sizeof(data));
pack << (BYTE)enDefaultEntitySystemID << (BYTE)sOpenCommonServer;
pack << (BYTE)flag;
GetGlobalLogicEngine()->GetEntityMgr()->BroadCast(data,pack.getPosition());
}
VOID CLogicServer::SetCommonServerId(const int nServerId)
{
if(m_bCommonServer)
{
m_nCommonServerId =0;
}
else
{
if(nServerId == m_nCommonServerId ) return; //
if(nServerId <= 0)
{
m_nCommonServerId =-1;
}
else
{
m_nCommonServerId = nServerId;
}
GetGlobalLogicEngine()->GetGlobalVarMgr().GetVar().set("VarCommonServerId", m_nCommonServerId);
}
OutputMsg(rmTip,"Mgr Set CommonSrvId =%d",m_nCommonServerId);
}
void CLogicServer::ReloadCrossConfig(bool bReload)
{
CLogicServerConfig config;
//config.LoadCrossServerConfig(this,bReload);
CDataPacket& DataPacket =GetDbClient()->allocProtoPacket(jxInterSrvComm::DbServerProto::dcReloadCrossConfig);
int nServerId = GetServerIndex();
DataPacket << nServerId << nServerId;
DataPacket.writeString(m_szCommonDbSrvIp);
DataPacket << (int) m_nCommonDbSrvPort; //公共数据服的地址
GetDbClient()->flushProtoPacket(DataPacket);
int nCommonServerId =GetCommonServerId();
if(nCommonServerId >= 0 )
{
SetStartCommonServer(true);
}
else
{
SetStartCommonServer(false);
}
//发送到会话
GetSessionClient()->SendServerIndex();
OutputMsg(rmTip,"ReloadCrossConfig,,dbprot=%d,nCommonServerId=%d",(int)m_nCommonDbSrvPort,nCommonServerId);
}
int CLogicServer::GetCommonServerRandPort()
{
int nport = m_maxCommonPort - m_minCommonPort;
int nRandIndex = 0;
if(nport > 0)
{
return m_minCommonPort + wrand(nport +1);
}
else
{
return m_minCommonPort;
}
}
VOID CLogicServer::OnStartedServer()
{
//服务器启动的时候
int nSvrId = -1;
CCLVariant * pVar = GetGlobalLogicEngine()->GetGlobalVarMgr().GetVar().get("VarCommonServerId");
if (pVar != NULL)
{
nSvrId = (int)((double)*pVar);
}
SetCommonServerId(nSvrId);
ReloadCrossConfig();
}
INT_PTR CLogicServer::GetStrLenUtf8(LPCTSTR sName)
{
LPCSTR sptr;
INT_PTR nLen = 0;
unsigned char ch;
for ( sptr = sName; *sptr; ++sptr )
{
ch = (unsigned char)*sptr;
if((ch & 0xF8) == 0xF8) //5个字节111110xx 10xxxxxx 10xxxxxx 10xxxxxx
{
sptr += 4;
}
else if( (ch & 0xF0) == 0xF0 )//4个字节11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
{
sptr += 3;
}
else if( (ch & 0xE0) == 0xE0)//3个字节1110xxxx 10xxxxxx 10xxxxxx
{
sptr += 2;
}
else if( (ch & 0xC0) == 0xC0 )//2个字节110xxxxx 10xxxxxx
{
sptr += 1;
}
nLen++;
//增加一个判断,防止恶意输入
if(nLen >1000)
{
break;
}
}
return nLen;
}
VOID CLogicServer::SendCurrencyLocalLog(WORD nLogId,
unsigned int nActorId,LPCTSTR sActorName,LPCTSTR sAccount,
WORD nLogType,WORD nCurrencyType,INT64 nAmount,INT64 nBalance,WORD nIsShop,int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendCurrencyLog(nLogId,nActorId,sActorName,sAccount,nLogType, nCurrencyType, nAmount, nBalance, nIsShop,nSrvId);
}
VOID CLogicServer::SendCurrencyLocalLog(WORD nLogId,CActor *pActor,WORD nLogType,WORD nCurrencyType,INT64 nAmount,INT64 nBalance,WORD nIsShop,int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendCurrencyLog(nLogId,pActor,nLogType, nCurrencyType, nAmount, nBalance, nIsShop,nSrvId);
}
VOID CLogicServer::SendShopLocalLog(INT nItemId,
unsigned int nActorId,LPCTSTR sActorName,LPCTSTR sAccount,
WORD nShopType,WORD nItemType,WORD nItemNum,WORD nCurrencyType,INT64 nConsumeNum, int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendShopLog(nItemId,nActorId,sActorName,sAccount,nShopType,nItemType,nItemNum,nCurrencyType,nConsumeNum,nSrvId);
}
VOID CLogicServer::SendShopLocalLog(INT nItemId,CActor *pActor,WORD nShopType,WORD nItemType,WORD nItemNum,WORD nCurrencyType,INT64 nConsumeNum, int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendShopLog(nItemId,pActor,nShopType,nItemType,nItemNum,nCurrencyType,nConsumeNum,nSrvId);
}
VOID CLogicServer::SendItemLocalLog(
WORD nLogId,
unsigned int nActorId, //玩家id
unsigned int nAccountId, //角色ID
LPCTSTR sActorName,
LPCTSTR sAccount,
INT nItemId, WORD nItemType, WORD nItemNum, WORD nOperType, int nSrvId)
{
if(m_pLocalClient)
{
const LPCSTR pLogreson = (nLogId >= GameLog::Log_Max) ? "该日志id有误" : GameLog::LogItemReason[nLogId];
m_pLocalClient->SendItemLog(nItemId, nActorId, sActorName, sAccount, nItemType, nItemNum, nOperType, pLogreson, nSrvId);
}
}
VOID CLogicServer::SendItemLocalLog(WORD nLogId,CActor *pActor,INT nItemId,WORD nItemType,WORD nItemNum,WORD nOperType, int nSrvId)
{
if(m_pLocalClient)
{
const LPCSTR pLogreson = (nLogId >= GameLog::Log_Max) ? "该日志id有误" : GameLog::LogItemReason[nLogId];
m_pLocalClient->SendItemLog(nItemId,pActor,nItemType,nItemNum,nOperType,pLogreson,nSrvId);
}
}
VOID CLogicServer::SendTaskLocalLog(INT nTaskId,
unsigned int nActorId,LPCTSTR sActorName,LPCTSTR sAccount,
WORD nTaskType,WORD nStatu, int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendTaskLog(nTaskId,nActorId,sActorName,sAccount,nTaskType,nStatu,nSrvId);
}
VOID CLogicServer::SendTaskLocalLog(INT nTaskId,CActor *pActor,WORD nTaskType,WORD nStatu, int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendTaskLog(nTaskId,pActor,nTaskType,nStatu,nSrvId);
}
VOID CLogicServer::SendActivityLocalLog(INT nAtvId,
unsigned int nActorId,LPCTSTR sActorName,LPCTSTR sAccount,
WORD nAtvType,WORD nStatu, int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendActivityLog(nAtvId,nActorId,sActorName,sAccount,nAtvType,nStatu,nSrvId);
}
VOID CLogicServer::SendActivityLocalLog(INT nAtvId,CActor *pActor,WORD nAtvType,WORD nStatu, int nSrvId)
{
if(m_pLocalClient)
m_pLocalClient->SendActivityLog(nAtvId,pActor,nAtvType,nStatu);
}