This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

View File

@@ -0,0 +1,67 @@

#include "StdAfx.h"
VOID CCrossClient::OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket)
{
InHandle::OnPacket(nCmd,inPacket);
}
VOID CCrossClient::OnDisconnected()
{
m_dwDisconnectedTick = _getTickCount();
if ( registed() )
{
OutputMsg( rmWaning, _T("%s服务器(%s)(%s:%d)连接已断开"), getServerTypeName(getClientType()),
getClientName(), GetRemoteHost(), GetRemotePort() );
}
else
{
OutputMsg( rmWaning, _T("%s服务器(%s:%d)连接已断开"), getServerTypeName(getClientType()),
GetRemoteHost(), GetRemotePort() );
}
Inherited::OnDisconnected();
}
VOID CCrossClient::OnError(INT errorCode)
{
OutputError(errorCode, _T("%s服务器(%s)(%s:%d)套接字错误"), getServerTypeName(getClientType()),
getClientName(), GetRemoteHost(), GetRemotePort() );
Inherited::OnError(errorCode);
}
VOID CCrossClient::OnRun()
{
}
bool CCrossClient::OnValidateRegData(const jxSrvDef::PSERVER_REGDATA pRegData)
{
//游戏服和db能够登陆
if ( pRegData->GameType == SERVER_REGDATA::GT_JianXiaoJiangHu &&
( pRegData->ServerType == GameServer || pRegData->ServerType == DBServer) )
{
return true;
}
else
{
return false;
}
}
void CCrossClient::OnRegDataValidated()
{
}
void CCrossClient::OnSendReqCommonPlatformResult(CDataPacketReader &inPacket)
{
// unsigned int nAccountId = 0, nActorId = 0;
// int nServerIndex = 0,nDestServerId = 0, nType = 0, nResult = 0;
// inPacket >> nDestServerId;
// inPacket >> nAccountId >> nActorId;
// inPacket >> nType >> nResult;
// CDataPacket &packet = allocProtoPacket(SessionServerProto::sReqestPlatformAck);
// packet << (unsigned int)nActorId << (BYTE)SessionServerProto::neSuccess;
// packet << (unsigned int)nAccountId << (int)nDestServerId << (int)nResult << (int)nType;
// flushProtoPacket(packet);
}

View File

@@ -0,0 +1,80 @@
#ifndef _CROSS_CLIENT_H_
#define _CROSS_CLIENT_H_
/*****************************************************************
            Copyright (c) 2021, 上海漫方网络科技有限公司
                    All rights reserved
       
    创建日期  2021年04月28日 14时01分
    文件名称  CrossClient.h
    说    明:  数据引擎连接到跨服服务器的客户端类
    
    当前版本  1.00
    作    者:  
    概    述:  数据引擎连接到跨服服务器的客户端类
*****************************************************************/
using namespace wylib::sync::lock;
class CCrossServerManager;
class CCrossServer;
using namespace jxSrvDef;
class CCrossClient
: public CCustomJXServerClientSocket,
public CCrossDataHandle
{
friend class CCrossServer;
public:
typedef CCustomJXServerClientSocket Inherited;
typedef CCrossDataHandle InHandle;
protected:
//VOID ProcessRecvBuffers(PDATABUFFER pDataBuffer);
VOID DispatchRecvMsg(CDataPacketReader & reader);
//实现虚接口
VOID OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket);
bool OnValidateRegData(const jxSrvDef::PSERVER_REGDATA pRegData) ;
virtual void OnRegDataValidated();
protected:
VOID OnDisconnected();
VOID OnError(INT errorCode);
//覆盖父类例行执行的函数
VOID OnRun();
//由SessionServer调用的例行执行函数
inline VOID Run(){ SingleRun(); }
protected:
//重写收 发包的函数
virtual CDataPacket& AllocDataPacket(const jxSrvDef::INTERSRVCMD nCmd)
{
return Inherited::allocProtoPacket(nCmd);
}
virtual void FlushDataPacket(CDataPacket &packet)
{
return Inherited::flushProtoPacket(packet);
}
public:
CCrossClient(){}
~CCrossClient(){}
//反馈是否可以跨平台的消息给逻辑服
void OnSendReqCommonPlatformResult(CDataPacketReader &inPacket);
private:
int nCrossSrvId;//跨服id
TICKCOUNT m_dwDisconnectedTick;//断开连接的时间
static const size_t MaxSSDataSize = 4096;//向会话服务器发送的单个数据包大小的最大值
typedef VOID (CCrossClient::*OnHandleSockPacket)(CDataPacketReader &packet);
static const size_t MaxForwardLogicDataSize = 40960; // 最大数据包为40k
//大型SQL查询语句缓冲长度
static const SIZE_T dwHugeSQLBufferSize = 1024 * 1024 * 2;
};
#endif

View File

@@ -0,0 +1,83 @@

#include "StdAfx.h"
#include "CrossDataHandle.h"
using namespace jxInterSrvComm::SessionServerProto;
CCrossDataHandle::CCrossDataHandle()
{
m_nSelfServerId =0;
m_dwDisconnectedTick = 0;
m_pSSServer = NULL;
m_pForwardDataBuff= NULL;
}
CCrossDataHandle::~CCrossDataHandle()
{
//m_Allocator.FreeBuffer(m_pHugeSQLBuffer);
if(m_pForwardDataBuff)
{
delete []m_pForwardDataBuff;
m_pForwardDataBuff =0;
}
}
void CCrossDataHandle::SetParam(CCrossServer *pSessionSrv, bool isSessonConnect )
{
m_pSSServer = pSessionSrv;
}
//处理logic发送到的消息
VOID CCrossDataHandle::OnPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket)
{
switch (nCmd)
{
case jxInterSrvComm::CrossServerProto::cReqCrossLogin:
case jxInterSrvComm::CrossServerProto::cSendCrossData:
case jxInterSrvComm::CrossServerProto::cSendCloseActor:
case jxInterSrvComm::CrossServerProto::cGetCrossActorId:
case jxInterSrvComm::CrossServerProto::cCSGetRankList:
case jxInterSrvComm::CrossServerProto::cGetActorOfflineData:
case jxInterSrvComm::CrossServerProto::cSendReqChat:
{
int nSrvId = 0;
unsigned int nActorId = 0;
// BYTE nType = 0;
// inPacket >> nSrvId >> nActorId >> nType;
// printf("C2L_ReqLoginData nSrvId:%d, nActorId:%d, nType:%d\n",nSrvId,nActorId,nType);
CDataPacket &packet = AllocDataPacket(0);
packet.setPosition(0);
// inPacket >> nSrvId >> nActorId;
// packet<< nSrvId << nActorId;
// packet.adjustOffset(0-sizeof(jxSrvDef::INTERSRVCMD)); // 将Offset回退到消息ID的位置
packet.writeBuf(inPacket.getOffsetPtr(), inPacket.getLength()- inPacket.getPosition());
//通知逻辑可以初始化数据
GetGlobalLogicEngine()->GetNetWorkHandle()->PostInternalMessage(SSM_LOGIC_2_CROSS_DATA,
nCmd,
(Uint64)(&packet)
);
}break;
default:
break;
}
}
VOID CCrossDataHandle::BroadcastMessage2Logic(const INT_PTR nServerIndex, LPCSTR sMsg, const size_t dwSize)
{
if (!m_pSSServer && nServerIndex < 0)
return;
if (0 == nServerIndex)
m_pSSServer->SendMsg2AllClient(GameServer, sMsg, dwSize);
else
m_pSSServer->SendMsg2LogicClient(nServerIndex, sMsg, dwSize);
}

View File

@@ -0,0 +1,120 @@
#ifndef _SESSION_HANDLE_H_
#define _SESSION_HANDLE_H_
/*****************************************************************
            Copyright (c) 2021, 上海漫方网络科技有限公司
                    All rights reserved
       
    创建日期  2021年04月28日 14时01分
    文件名称  CrossDataHandle.h
    说    明:  跨服引擎分发消息
    
    当前版本  1.00
    作    者:  
    概    述:  跨服引擎分发消息类
*****************************************************************/
using namespace wylib::sync::lock;
class CCrossServerManager;
class CCrossServer;
class ISessionRequestHost
{
public:
/*
* Comments: 分配数据包
* Param const jxSrvDef::INTERSRVCMD nCmd:
* @Return CDataPacket&:
* @Remark:
*/
virtual CDataPacket& AllocDataPacket(const jxSrvDef::INTERSRVCMD nCmd) = 0;
/*
* Comments: 刷新数据包到发送队列
* Param CDataPacket &packet
* @Return void:
* @Remark:
*/
virtual void FlushDataPacket(CDataPacket &packet) = 0;
};
using namespace jxSrvDef;
class CCrossDataHandle :public ISessionRequestHost
{
friend class CCrossServer;
protected:
//VOID ProcessRecvBuffers(PDATABUFFER pDataBuffer);
VOID DispatchRecvMsg(CDataPacketReader & reader);
//VOID SendKeepAlive();
//实现虚接口
VOID OnPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket);
public:
CCrossDataHandle( );
~CCrossDataHandle();
void SetParam(CCrossServer *pSessionSrv, bool isSessonConnect );
//获取服务器的id
inline int GetServerId()
{
return m_nSelfServerId;
}
/*
* Comments: 处理来自逻辑服务器的请求传送到目标服务器消息
* Param CatchDefaultPacket:
* Param & inPacket:
* @Return VOID:
* @Remark:
*/
VOID CatchRequestTransmit(CDataPacketReader &inPacket) {};
/*
* Comments: 收到战区的数据
* Param CDataPacketReader & inPacket:
* @Return VOID:
* @Remark:
*/
VOID CatchGroupMessage(CDataPacketReader &inPacket) {};
// VOID BroadcastMessage2Logic(CDataPacketReader &inPacket);
VOID BroadcastMessage2Logic(const INT_PTR nServerIndex, LPCSTR sMsg, const size_t dwSize);
/*
* Comments: 保存跨服排行榜
* Param CDataPacketReader & inPacket:
* @Return VOID:
* @Remark:
*/
VOID CatchSaveCsRank(CDataPacketReader &inPacket) {};
/*
* Comments: 获取跨服排行榜
* Param CDataPacketReader & inPacket:
* @Return VOID:
* @Remark:
*/
VOID CatchLoadCsRank(CDataPacketReader &inPacket) {};
public:
static const size_t MaxSSDataSize = 4096;//向会话服务器发送的单个数据包大小的最大值
static const size_t MaxForwardLogicDataSize = 40960; // 最大数据包为40k
char *m_pForwardDataBuff; // 公共逻辑服务器SessionClient用于转发公共服务器消息的Buff长度固定MaxForwardLogicDataSize
private:
int m_nSelfServerId; //自身的服务器ID,用于数据转发
CCrossServer* m_pSSServer; //所属会话服务器
TICKCOUNT m_dwDisconnectedTick;//断开连接的时间
char m_sTrServerIndex[24] ; //格式化的服务器的index用于连接的时候快速计算
bool m_bIsCrossSession; //是否是跨服的会话传输的client跨服的会话有些东西要特殊处理下
};
#endif

View File

@@ -0,0 +1,73 @@
#ifndef _CROSS_PROTO_H_
#define _CROSS_PROTO_H_
/*
CopyRight@2021 跨服通用结构
author: 马海龙
time: 2021-04-28
*/
/**
全局会话结构
在修改此结构的时候需要注意一下结构大小通过内存池申请的中等包的大小是256字节
如果此结构大于256字节且小于64K则会造成较多的内存浪费
**/
typedef struct tagGameCross
{
Uint64 nSessionID; //会话ID
int nServerIndex; //会话登录的服务器ID
int nIsRawLogin; //是否在原始服务器登录
LONGLONG nIPAddr; //会话登录的IP地址支持IPv6
TICKCOUNT dwSessionTick; //会话建立的时间
jxSrvDef::GSSTATE nState; //会话状态(登录、查询角色还是已经进入游戏)
jxSrvDef::ACCOUNT sAccount; //会话账号
TICKCOUNT dwTimeOut; //会话超时时间(在等待查询角色以及等待进入游戏状态下有效)
int nConfimSrvCount;//确认会话是否登录,需要等待回应的服务器数量
UINT64 lKey; //登陆的随机key
}GAMECROSS, *PGAMECROSS;
/*
** 记录逻辑服务器ID、服务器名称以及连接的公共服务器ID等信息
*/
typedef struct tagLogicServerInfo
{
int server_id; // 服务器ID
int cserver_id; // 连接的公共服务器ID
char serverName[32]; // 服务器名称
}LOGICSERVERINFO, *PLOGICSERVERINFO;
//客户端登录失败错误号
#define LOGINERR_USRNOTEXISTS -1 //用户不存在
#define LOGINERR_PSWDFAILURE -2 //密码错误
#define LOGINERR_USERDISABLED -3 //账号已被禁用
#define LOGINERR_USERNOTAVAILABLE -4 //尚未激活游戏
#define LOGINERR_LOGINLOCKCHECKFAIL -5 //
#define LOGINERR_DISABLELOGINTHISGAME -6 //
#define LOGINERR_ALREADYLOGIN -7
#define LOGINERR_SERVERBUSY -8
#define LOGINERR_LOGINONWAITING -9
#define LOGINERR_INPUT_SECURENUMBER -10
#define LOGINERR_USERFULL -11
/* 网关模块内部消息定义
*******************************************/
#define GTIM_CONFIM_SESSION_RESULT 10001 //会话服务器向网关用户投递确认会话是否在线的结果(Param1=会话IDParam2=是否在线(0:1))
#define GTIM_CONFIRM_OPEN_SESSION 10012 //确认已经打开了会话
/* 跨服服务器模块内部消息定义
*******************************************/
#define CSIM_POST_CLOSE_SESSION 20001 //按会话ID关闭会话(Param1=会话ID,Param2=会话连续在线时间(用于防沉迷中统计在线时间))
#define CSIM_USER_EXISTS_OF_SESSION_RESULT 20002 //网关按会话ID检查用户是否存在后向DBSSClient返回的消息(Param1=会话ID,Param2=BOOL)
#define CSIM_CHANGE_SESSION_STATE 20003 //网关向SessionServer投递改变会话状态的消息(Param1=会话ID,Param2=会话状态)
#define CSIM_GATE_USER_CLOSED 20004 //网关向SessionServer投递网关用户已关闭的消息(Param1=会话ID)
#define CSIM_POST_ALL_CLIENT_MSG 20005 //向所有会话服务器的客户端发送消息(Param1=服务器类型,Param2=数据包,Param3=数据包大小)
#define CSIM_CONFIM_SESSION_ONLINE 20006 //确认会话是否在线(Param1=会话ID,Param2=服务器ID)
#define CSIM_CONFIM_SESSION_RESULT 20007 //数据或引擎客户端返回会话是否在线(Param1=会话ID,Param2=是否在线0:1)
#define CSIM_CLOSE_SESSION_BY_ACCOUNT 20008 //通过账号字符串查找并关闭会话(Param1=字符串指针)
#define CSIM_CLOSE_SESSION_BY_ACCOUNTID 20012 //通过accountid关闭会话
#define CSIM_KICK_ONLINE_CROSSSERVER_ACTOR 20013 //踢掉在线的跨服用户
#endif //_CROSS_PROTO_H_

View File

@@ -0,0 +1,821 @@
#include "StdAfx.h"
CCrossServer::CCrossServer(CCrossServerManager *lpSSManager)
:Inherited()
{
m_pCSManager = lpSSManager;
m_nEngineClientCount = 0;
m_dwCheckOnlineLogTick = 0;
m_boOnlineLoged = FALSE;
m_dwCheckOnlineLogTick =0;
m_SessionList.setLock(&m_SessionListLock);
SetServiceName(_T("会话"));
}
CCrossServer::~CCrossServer()
{
}
VOID CCrossServer::SendLogOnlineCount()
{
}
typedef struct tagIpCount
{
long long lIp; //IP
long long nCount; //登陆的数目
} IPCOUNT;
//发送当前ip的状况
void CCrossServer::SendOnlineIpStatus()
{
}
CCustomServerClientSocket* CCrossServer::CreateClientSocket(SOCKET nSocket, PSOCKADDR_IN pAddrIn)
{
CCrossClient * pClient = new CCrossClient ;
pClient->SetClientSocket(nSocket, pAddrIn);
pClient->SetParam(this,false);
return pClient;
}
VOID CCrossServer::ProcessClients()
{
INT_PTR i;
INT_PTR nDBCount = 0, nEngineCount = 0;
CCrossClient *pClient;
TICKCOUNT dwCurTick = _getTickCount();
//循环处理每个客户端连接
m_ClientList.flush();
//必须降序循环,因为列表中的数据可能在循环中被移除
for ( i=m_ClientList.count() - 1; i>-1; --i )
{
pClient = (CCrossClient*)m_ClientList[i];
//处理活动的连接
pClient->Run();
//删除断开的连接
if ( !pClient->connected() )
{
//连接在断开后的5分钟后删除
if ( dwCurTick - pClient->m_dwDisconnectedTick >= 5 * 60 * 1000 )
{
m_ClientList.lock();
m_ClientList.remove(i);
m_ClientList.unlock();
delete pClient;
}
continue;
}
}
}
BOOL CCrossServer::DoStart()
{
return TRUE;
}
VOID CCrossServer::DoStop()
{
}
//跨服逻辑处理
VOID CCrossServer::DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4)
{
INT_PTR nIndex;
// Inherited::DispatchInternalMessage(uMsg,uParam1,uParam2,uParam3,uParam4); //先执行父类的消息处理
if(uMsg == SSM_CROSS_2_LOGIC_DATA)
{
//客户端请求逻辑服逻辑服请求跨服产生玩家对应的跨服唯一id
if(uParam1 == jxInterSrvComm::CrossServerProto::sGetCrossActorId) //
{
char sBuffer[64];
int nCrossServerIndex = uParam2;
int nActorId = uParam3;
int nCrossActorId = uParam4;
CDataPacket data(sBuffer,sizeof(sBuffer));
PDATAHEADER pheader;
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data <<(WORD)jxInterSrvComm::CrossServerProto::sGetCrossActorId;
data << nActorId << nCrossActorId;
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
SendMsg2LogicClient(nCrossServerIndex,data.getMemoryPtr(), data.getLength());
}
else if(uParam1 == jxInterSrvComm::CrossServerProto::sSendCSMail ||
uParam1 == jxInterSrvComm::CrossServerProto::sCSGetRankList) //
{
char sBuffer[7168];
CDataPacket data(sBuffer,sizeof(sBuffer));
PDATAHEADER pheader;
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data <<(WORD)uParam1;
CDataPacket *outPacket = (CDataPacket*)uParam2;
int nCrossServerIndex = 0;
if(outPacket) {
outPacket->setPosition(0);
// printf("size:%d\n",outPacket->getLength() - outPacket->getPosition());
if(uParam1 == jxInterSrvComm::CrossServerProto::sSendCSMail)
{
int nActorId = 0;
(*outPacket) >> nActorId >> nCrossServerIndex;
// printf("cSendCSMail:nActorId:%d,nCrossServerIndex:%d\n",nActorId, nCrossServerIndex);
data << nActorId;
}
else if(uParam1 == jxInterSrvComm::CrossServerProto::sCSGetRankList)
{
(*outPacket) >> nCrossServerIndex;
}
}
data.writeBuf(outPacket->getOffsetPtr(),outPacket->getLength() - outPacket->getPosition());
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
SendMsg2LogicClient(nCrossServerIndex,data.getMemoryPtr(), data.getLength());
CLocalCrossClient *pClient = (CLocalCrossClient *)(uParam4);
if (pClient)
pClient->FreeBackUserDataPacket(outPacket);
}
else if (uParam1 == jxInterSrvComm::CrossServerProto::sGetActorOfflineData)
{
CDataPacket *outPacket = (CDataPacket*)uParam2;
if(outPacket)
{
outPacket->setPosition(0);
int nCrossServerIndex = 0;
(*outPacket) >> nCrossServerIndex;
CDataPacket &data = allocSendPacket();
PDATAHEADER pheader;
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data <<(WORD)uParam1;
data.writeBuf(outPacket->getOffsetPtr(),outPacket->getLength() - outPacket->getPosition());
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag = DEFAULT_TAG_VALUE;
pheader->len = data.getLength() - sizeof(*pheader);
SendMsg2LogicClient(nCrossServerIndex, data.getMemoryPtr(), data.getLength());
}
}
else if(uParam1 == jxInterSrvComm::CrossServerProto::sSendReqChat) //
{
//char sBuffer[1024];
CDataPacket *outPacket = (CDataPacket*)uParam2;
if(outPacket)
{
outPacket->setPosition(0);
int nLogicServerIndex = 0;
(*outPacket) >> nLogicServerIndex;
printf("size:%d\n", outPacket->getLength()- outPacket->getPosition());
printf("sSendReqChat: nCrossServerIndex:%d\n", nLogicServerIndex);
//CDataPacket data(sBuffer, sizeof(sBuffer));
CDataPacket &data = allocSendPacket();
PDATAHEADER pheader;
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data << (WORD)uParam1;
data.writeBuf(outPacket->getOffsetPtr(), outPacket->getLength() - outPacket->getPosition());
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag = DEFAULT_TAG_VALUE;
pheader->len = data.getLength() - sizeof(*pheader);
SendMsg2LogicClient(nLogicServerIndex, data.getMemoryPtr(), data.getLength());
//GetLogicServer()->GetCrossClient()->FreeBackUserDataPacket(outPacket);
}
CLocalCrossClient *pClient = (CLocalCrossClient *)(uParam4);
if (pClient)
{
pClient->FreeBackUserDataPacket(outPacket);
}
}
else if( uParam1 == jxInterSrvComm::CrossServerProto::sSendBroadTipmsg
|| uParam1 == jxInterSrvComm::CrossServerProto::sSendBroadSysTipmsg)
{
//char sBuffer[1024];
CDataPacket *outPacket = (CDataPacket*)uParam2;
if(outPacket)
{
outPacket->setPosition(0);
//int nCrossServerIndex = 0;
//(*outPacket) >> nCrossServerIndex;
printf("size:%d\n", outPacket->getLength()- outPacket->getPosition());
//CDataPacket data(sBuffer, sizeof(sBuffer));
CDataPacket &data = allocSendPacket();
PDATAHEADER pheader;
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data << (WORD)uParam1;
data.writeBuf(outPacket->getOffsetPtr(), outPacket->getLength() - outPacket->getPosition());
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag = DEFAULT_TAG_VALUE;
pheader->len = data.getLength() - sizeof(*pheader);
SendMsg2AllClient(GameServer, data.getMemoryPtr(), data.getLength());
//GetLogicServer()->GetCrossClient()->FreeBackUserDataPacket(outPacket);
}
CLocalCrossClient *pClient = (CLocalCrossClient *)(uParam4);
if (pClient)
{
pClient->FreeBackUserDataPacket(outPacket);
}
}
}
}
void CCrossServer::ProcessKickCrossActor(const unsigned int nSessionId, const int nServerIndex)
{
char sBuffer[64];
PDATAHEADER pheader;
CDataPacket data(sBuffer,sizeof(sBuffer));
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data << 1;//(WORD)SessionServerProto::sKickCrossServerUser ;
data << (unsigned int)nSessionId;
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
OutputMsg(rmNormal,"send Kick cross server actor,accountid=%d,serverindex=%d",(int)nSessionId,(int)nServerIndex);
SendMsg2LogicClient(nServerIndex,data.getMemoryPtr(), data.getLength());
}
VOID CCrossServer::SingleRun()
{
TICKCOUNT dwCurTick = _getTickCount();
//提交新开启的会话数据
if ( m_SessionList.appendCount() > 0 )
{
m_SessionList.flush();
TRACE(_T("当前会话数量:%d"), m_SessionList.count());
}
//调用父类例行执行
Inherited::SingleRun();
}
bool CCrossServer::InitRankMsg()
{
return true;
}
bool CCrossServer::SaveRankMsg()
{
return true;
}
//初始化账户
bool CCrossServer::InitACCountId()
{
return true;
}
PGAMECROSS CCrossServer::GetSessionPtr(const unsigned int nSessionId,PINT_PTR lpIndex ,Uint64 lKey,int nServerIndex)
{
INT_PTR i;
PGAMECROSS *pSessionList;
bool bNeedCheckKey = (lKey == UINT64(-1));
pSessionList = m_SessionList;
for ( i=m_SessionList.count() - 1; i>-1; --i )
{
if ( pSessionList[i]->nSessionID == nSessionId && ( bNeedCheckKey==true || lKey ==pSessionList[i]->lKey ) && (nServerIndex ==-1 || nServerIndex ==pSessionList[i]->nServerIndex ))
{
if (lpIndex) *lpIndex = i;
return pSessionList[i];
}
}
return NULL;
}
//返回1个ip登陆了多少个号
int CCrossServer::GetLoginAccountCount(LONGLONG lIp)
{
INT_PTR i;
PGAMECROSS *pSessionList;
int nCount =0;
pSessionList = m_SessionList;
for ( i=m_SessionList.count() - 1; i>-1; --i )
{
if ( pSessionList[i]->nIPAddr == lIp && pSessionList[i]->nIsRawLogin)
{
nCount ++;
}
}
return nCount;
}
PGAMECROSS CCrossServer::GetSessionPtrByAccount(LPCSTR sAccount, PINT_PTR lpIndex)
{
INT_PTR i;
PGAMECROSS *pSessionList;
pSessionList = m_SessionList;
for ( i=m_SessionList.count() - 1; i>-1; --i )
{
if ( _stricmp(pSessionList[i]->sAccount, sAccount) == 0 )
{
if (lpIndex) *lpIndex = i;
return pSessionList[i];
}
}
return NULL;
}
BOOL CCrossServer::CloseSessionAtListIndex(const INT_PTR nIndex)
{
unsigned int nSessionId;
PGAMECROSS pSession;
BOOL boResult = FALSE;
//OutputMsg(rmNormal,"Current Thread =%d",(int)GetCurrentThreadId());
// if ( m_SessionList.count() > nIndex )
// {
// boResult = TRUE;
// pSession = m_SessionList[nIndex];
// nSessionId = (unsigned int)pSession->nSessionID;
// //关闭会话
// OutputMsg(rmTip,_T("close Session,ID=%u,account=%s,serverin=%d"),nSessionId,pSession->sAccount,(int)pSession->nServerIndex);
// //发给自己的服务器,需要删除这个会话
// BroadCastCloseSession(nSessionId,pSession->lKey,pSession->nServerIndex);
// //删除会话指针
// m_SessionList.lock();
// m_SessionList.remove(nIndex);
// m_SessionList.unlock();
// m_Allocator.FreeBuffer(pSession);
return boResult;
}
INT_PTR CCrossServer::SendMsg2AllClient(const SERVERTYPE eServerType, LPCSTR sMsg, const size_t dwSize)
{
INT_PTR i, nSendCount = 0;
CCrossClient *pClient;
for ( i=m_ClientList.count() - 1; i>-1; --i )
{
pClient = (CCrossClient*)m_ClientList[i];
if ( pClient && pClient->connected() && pClient->registed() )
{
if ( eServerType == InvalidServer || pClient->getClientType() == eServerType )
{
pClient->AppendSendBuffer(sMsg, dwSize );
nSendCount++;
}
}
}
return nSendCount;
}
INT_PTR CCrossServer::SendMsg2LogicClient(const INT_PTR nServerIndex, LPCSTR sMsg, const size_t dwSize)
{
INT_PTR i, nSendCount = 0;
CCrossClient *pClient;
for ( i=m_ClientList.count() - 1; i>-1; --i )
{
pClient = (CCrossClient*)m_ClientList[i];
if ( pClient && pClient->connected() && pClient->registed() && pClient->getClientType() == GameServer && pClient->getClientServerIndex() == (int)nServerIndex)
{
pClient->AppendSendBuffer(sMsg, dwSize );
nSendCount++;
}
}
return nSendCount;
}
INT_PTR CCrossServer::SendGroupLogicClientMsg(const int nCommServerId, LPVOID data, const SIZE_T nSize)
{
INT_PTR i, nSendCount = 0;
// CCrossClient *pClient;
// for (i = m_ClientList.count() - 1; i > -1; --i)
// {
// pClient = (CCrossClient*)m_ClientList[i];
// if ( pClient && pClient->registed()
// && GameServer == pClient->getClientType()
// && nCommServerId == pClient->GetCommonServerId())
// {
// pClient->AppendSendBuffer(data, nSize);
// nSendCount++;
// }
// }
return nSendCount;
}
INT_PTR CCrossServer::SendAllDBAndIndexEngineMsg(const INT_PTR nServerIndex, LPCSTR sMsg, const size_t dwSize)
{
INT_PTR i, nSendCount = 0;
CCrossClient *pClient;
m_ClientList.lock();
for ( i=m_ClientList.count() - 1; i>-1; --i )
{
pClient = (CCrossClient*)m_ClientList[i];
if ( !pClient || !pClient->connected() || !pClient->registed() )
continue;
if ( pClient->getClientType() == DBServer ||
(pClient->getClientType() == GameServer && pClient->getClientServerIndex() == nServerIndex) )
{
pClient->AppendSendBuffer(sMsg, dwSize );
nSendCount++;
}
}
m_ClientList.unlock();
return nSendCount;
}
INT_PTR CCrossServer::BroadCastUpdateSessionState(PGAMECROSS pSession)
{
char sBuffer[32];
PDATAHEADER pheader;
CDataPacket data(sBuffer,sizeof(sBuffer));
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data << 1;//(WORD)SessionServerProto::sUpdateSession ;
data << (int)pSession->nSessionID;
data << (int)pSession->nState;
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
//向所有数据服务器发送会话状态变更消息
INT_PTR nResult = SendMsg2AllClient(DBServer,data.getMemoryPtr(), data.getLength());
//如果会话登录到某个逻辑服务器,则向此逻辑服务器发送会话状态变更消息
if ( pSession->nServerIndex > 0 )
{
nResult += SendMsg2LogicClient(pSession->nServerIndex,data.getMemoryPtr(), data.getLength());
}
return nResult;
}
INT_PTR CCrossServer::BroadCastCloseSession(const UINT64 nSessionId,Uint64 lKey,const int nServerIndex)
{
char sBuffer[64];
PDATAHEADER pheader;
CDataPacket data(sBuffer,sizeof(sBuffer));
data.setLength(sizeof(*pheader));
//关闭号
data.setPosition(sizeof(*pheader));
data << 1;//(WORD)SessionServerProto::sCloseSession ;
data <<(unsigned int) nSessionId;
data <<(Uint64) lKey;
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
//向所有数据服务器、引擎服务器发送删除会话消息
if(nServerIndex >0 )
{
return SendMsg2LogicClient(nServerIndex, data.getMemoryPtr(), data.getLength()) ;
}
else
{
return SendMsg2AllClient(LogServer, data.getMemoryPtr(), data.getLength() );
}
//return SendAllClientMsg(InvalidServer, data.getMemoryPtr(), data.getLength());
}
INT_PTR CCrossServer::BroadCastSessionConfim(const UINT64 nSessionId, const INT_PTR nServerIndex)
{
INT_PTR nResult =0;
char sBuffer[32];
PDATAHEADER pheader;
CDataPacket data(sBuffer,sizeof(sBuffer));
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data << 1;//(WORD)SessionServerProto::sQuerySessionExist ;
data << (unsigned int)nSessionId;
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
//如果nServerIndex为0则向所有数据服务器、引擎服务器发送确认会话是否在线的消息
if ( !nServerIndex )
{
nResult = SendMsg2AllClient(InvalidServer, data.getMemoryPtr(), data.getLength());
}
else
{
nResult = SendAllDBAndIndexEngineMsg(nServerIndex, data.getMemoryPtr(), data.getLength());
}
return nResult;
}
//踢掉在线的用户
VOID CCrossServer::PostKickCrossActor(const INT_PTR nSessionId, const int nServerIndex)
{
PostInternalMessage(CSIM_KICK_ONLINE_CROSSSERVER_ACTOR, nSessionId,nServerIndex,0);
}
VOID CCrossServer::PostAllClientMsg(const SERVERTYPE eServerType, LPCSTR sMsg)
{
size_t dwSize = strlen(sMsg);
LPVOID lpData = m_Allocator.AllocBuffer(dwSize);
memcpy(lpData, sMsg, dwSize);
PostInternalMessage(CSIM_POST_ALL_CLIENT_MSG, eServerType, (UINT_PTR)lpData, dwSize);
}
BOOL CCrossServer::GetSession(const INT_PTR nSessionId, OUT PGAMECROSS pSession,int nServerIndex)
{
BOOL boResult = FALSE;
CSafeLock sl(&m_SessionListLock);
PGAMECROSS pSessionPtr = GetSessionPtr((unsigned int)nSessionId, NULL,Uint64(-1),nServerIndex);
if ( pSessionPtr )
{
*pSession = *pSessionPtr;
boResult = TRUE;
}
return boResult;
}
PGAMECROSS CCrossServer::GetSpecialServerSession(const INT_PTR nSessionId, const int nServerIndex)
{
INT_PTR i;
PGAMECROSS *pSessionList= m_SessionList;
for ( i=m_SessionList.count() - 1; i>-1; --i )
{
if ( pSessionList[i]->nSessionID == nSessionId && pSessionList[i]->nServerIndex == nServerIndex)
{
return pSessionList[i];
}
}
return NULL;
}
//logic server count
INT_PTR CCrossServer::GetLogicClientCount(const INT_PTR nServerIndex)
{
OutputMsg(rmTip,_T("GetLogicClientCount:%d"),nServerIndex);
if ( !nServerIndex )
return m_nEngineClientCount;
INT_PTR i, nResult = 0;
CCrossClient *pClient;
m_ClientList.lock();
for ( i=m_ClientList.count() - 1; i>-1; --i )
{
pClient = (CCrossClient*)m_ClientList[i];
////debug
//if (pClient)
//{
// OutputMsg(rmTip,_T("GetLogicClientCount pClient:connected=%d,registed=%d,clienttype=%d,serverindex=%d,clientName=%s"),
// (int)(pClient->connected()),(int)(pClient->registed()),pClient->getClientType(),
// pClient->getClientServerIndex(),pClient->getClientName());
//}
////end debug
if ( pClient && pClient->connected() && pClient->registed()
&& pClient->getClientType() == GameServer && pClient->getClientServerIndex() == nServerIndex )
{
nResult ++;
//OutputMsg(rmTip,_T("--------------------------%d"),pClient->getClientServerIndex());
////debug
//if (pClient)
//{
// OutputMsg(rmTip,_T("GetLogicClientCount pClient2:connected=%d,registed=%d,clienttype=%d,serverindex=%d,clientName=%s"),
// (int)(pClient->connected()),(int)(pClient->registed()),pClient->getClientType(),
// pClient->getClientServerIndex(),pClient->getClientName());
//}
////end debug
}
}
m_ClientList.unlock();
return nResult;
}
INT_PTR CCrossServer::UserCanLoginToServer(const INT_PTR nServerIndex)
{
INT_PTR i, nResult = -1;
CCrossClient *pClient;
// m_ClientList.lock();
// for ( i=m_ClientList.count() - 1; i>-1; --i )
// {
// pClient = (CCrossClient*)m_ClientList[i];
// if ( pClient && pClient->connected() && pClient->registed()
// && pClient->getClientType() == GameServer && pClient->getClientServerIndex() == nServerIndex )
// {
// //判断服务器人员是否已满,
// if ( pClient->m_nUserCount < pClient->m_nUserLimit )
// nResult = 0;
// else nResult = -1;
// break;
// }
// }
// m_ClientList.unlock();
return nResult;
}
//此函数是被网关线程调用的
BOOL CCrossServer::PostOpenSession(const INT_PTR nServerIndex,
const INT_PTR nRawServerIndex,
LPCSTR sAccount,
const unsigned int nSessionId,
const INT_PTR nIPAddr,
const INT_PTR dwTodayOnlineSec,
INT_PTR nGmLevel,
UINT64 lKey ,
INT_PTR nGateIndex,
bool bIsWhiteLogin,
bool bCommonMsg
)
{
char sBuffer[256];
PGAMECROSS pSession;
BOOL boNewSession = FALSE;
m_SessionList.lock();
pSession = GetSessionPtr(nSessionId);
m_SessionList.unlock();
if ( !pSession )
//每次都去new一个
{
pSession = (PGAMECROSS)m_Allocator.AllocBuffer(sizeof(*pSession));
boNewSession = TRUE;
}
ZeroMemory(pSession, sizeof(*pSession));
pSession->nSessionID = nSessionId;
pSession->nServerIndex = (int)nServerIndex;
if(nServerIndex == nRawServerIndex)
{
pSession->nIsRawLogin =1 ; //原来的服务器ID
}
else
{
pSession->nIsRawLogin =0;
}
pSession->nIPAddr = nIPAddr;
//会话建立的时候就标记为等待查询角色状态,这个时候将连接数据服务器
pSession->nState = gsWaitQueryChar;
pSession->dwSessionTick = _timeGetTime();
_asncpytA(pSession->sAccount, sAccount);
//追加会话数据
if ( boNewSession )
{
m_SessionList.append(pSession);
}
//向日志服务器记录登录日志格式为USERID/ACCOUNT/GAMETYPE/IPADDR/CHARNAME
//广播消息
GLOBALSESSIONOPENDATA SessionData ;
SessionData.nSessionId = (INT)nSessionId;
SessionData.nServerIndex = (INT)nServerIndex; //?
SessionData.nRawServerId = (INT)nRawServerIndex;
SessionData.nClientIPAddr = (LONGLONG)nIPAddr;
SessionData.dwFCMOnlineSec = (DWORD)dwTodayOnlineSec;
SessionData.nGmLevel =(int) nGmLevel; //GM等级
SessionData.lKey =lKey;
SessionData.nGateIndex = (int)nGateIndex; //在服务器的index
SessionData.eState =(GSSTATE) (bIsWhiteLogin?0:1);
_asncpytA(SessionData.sAccount, sAccount);
PDATAHEADER pheader;
CDataPacket data(sBuffer,sizeof(sBuffer));
data.setLength(sizeof(*pheader));
data.setPosition(sizeof(*pheader));
data << 1;//(WORD)SessionServerProto::sOpenSession ; //cmd
data << SessionData; //数据
pheader = (PDATAHEADER)data.getMemoryPtr();
pheader->tag=DEFAULT_TAG_VALUE ;
pheader->len = data.getLength() - sizeof(*pheader) ;
if(bCommonMsg == false)
{
//只向特定的逻辑服发送
SendMsg2LogicClient(nServerIndex, data.getMemoryPtr(), data.getLength());
}
return TRUE;
}
VOID CCrossServer::PostCloseSessionByAccountId(Uint64 nAccountId,UINT64 lKey)
{
PostInternalMessage(CSIM_CLOSE_SESSION_BY_ACCOUNTID, nAccountId, lKey,0,0);
}
VOID CCrossServer::PostCloseSessionByAccount(const LPCSTR sAccount)
{
LPSTR sAccountStr = (LPSTR)m_Allocator.AllocBuffer(sizeof(sAccountStr[0]) * (strlen(sAccount) + 1));
strcpy(sAccountStr, sAccount);
PostInternalMessage(CSIM_CLOSE_SESSION_BY_ACCOUNT, (UINT_PTR)sAccountStr, 0, 0);
}
VOID CCrossServer::EnumConnections(EnumConnectionFn lpFn, LPCVOID lpParam)
{
CCrossClient *pClient;
UINT uRetCode;
m_ClientList.lock();
for ( INT_PTR i=m_ClientList.count() - 1; i>-1; --i )
{
pClient = (CCrossClient*)m_ClientList[i];
if ( pClient && pClient->connected())
{
uRetCode = lpFn(lpParam, pClient);
if ( uRetCode )
break;
}
}
m_ClientList.unlock();
}
/*
* Comments: 解封ip
* Parameter: long long lIp:
* @Return void:
*/
long long CCrossServer::GetIntIp(char *sIp)
{
}
void CCrossServer::OnSendPlatformResultToClient(int nServerIndex,CDataPacketReader &inPacket)
{
CCrossClient *pClient = 0;
for (INT_PTR i= m_ClientList.count() - 1; i > -1; --i)
{
pClient = (CCrossClient*)m_ClientList[i];
if (pClient && pClient->connected() && pClient->getClientType() == GameServer)
{
if(pClient->GetServerId() == nServerIndex)
{
pClient->OnSendReqCommonPlatformResult(inPacket);
return;
}
}
}
}

View File

@@ -0,0 +1,181 @@
#ifndef _CROSS_SERVER_H_
#define _CROSS_SERVER_H_
/*****************************************************************
            Copyright (c) 2021, 上海漫方网络科技有限公司
                    All rights reserved
       
    创建日期  2021年04月28日 14时01分
    文件名称  CrossServer.h
    说    明:  跨服引擎类
    
    当前版本  1.00
    作    者:  
    概    述:  跨服引擎类
*****************************************************************/
class CCrossClient;
class CCrossServerManager;
using namespace jxSrvDef;
class CCrossServer
: public CCustomServerSocket
{
public:
friend class CCrossClient;
typedef CCustomServerSocket Inherited;
//定义枚举客户连接的回调函数类型第一个LPVOID类型的参数是一个穿透性的参数。函数返回0表示继续枚举否则表示终止枚举
typedef UINT (__stdcall *EnumConnectionFn) (LPCVOID, CCrossClient*);
private:
//发送记录各个服务器的在线人数
VOID SendLogOnlineCount();
protected:
//覆盖创建连接对象的函数
CCustomServerClientSocket* CreateClientSocket(SOCKET nSocket, PSOCKADDR_IN pAddrIn);
//覆盖处理客户端连接的函数
VOID ProcessClients();
//覆盖的开启服务的函数
BOOL DoStart();
//覆盖的停止服务的函数
VOID DoStop();
//覆盖内部消息分派函数
VOID DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4);
//覆盖例行执行函数
VOID SingleRun();
private:
//关闭会话操作的依据是会话在列表中的索引而非会话ID或账号字符串
BOOL CloseSessionAtListIndex(const INT_PTR nIndex);
private:
//向所有DB客户端以及指定ID的引擎客户端发送消息消息将被立刻追加到客户端发的发送缓冲中。数据包必须是完成的格式包含包头和包尾
INT_PTR SendAllDBAndIndexEngineMsg(const INT_PTR nServerIndex, LPCSTR sMsg, const size_t dwSize);
//广播会话状态变更的消息
INT_PTR BroadCastUpdateSessionState(PGAMECROSS pSession);
/*
* Comments:广播删除一个会话如果nServerIndex=-1则所有的广播否则只向特定的服务器广播
* Param const UINT64 nSessionId:会话的id
* Param const int nServerIndex:服务器的编号
* @Return INT_PTR:
*/
INT_PTR BroadCastCloseSession(const UINT64 nSessionId,Uint64 lKey, const int nServerIndex=-1 );
//广播确认会话是否在线
INT_PTR BroadCastSessionConfim(const UINT64 nSessionId, const INT_PTR nServerIndex);
//广播要删除这个玩家,玩家登陆的时候,如果在线,直接踢出这个角色
//INT_PTR BroadcastKickUser(const INT_PTR nSessionId,const INT_PTR nServerIndex);
//初始化账户的唯一为了保证账户的唯一account的最小值为 spguid << 24 +1 ,这样保证全球所有的账户都是唯一的
bool InitACCountId();
//初始化所有的数据
bool InitRankMsg();
//保存所有的rank数据
bool SaveRankMsg();
//向日志服发送当前ip的登陆情况
void SendOnlineIpStatus();
//获取int类型的ip
long long GetIntIp(char *sIp); //
public:
//通过账号字符串获取会话指针如果lpIndex参数非空则会向指针指向的内存填充值为会话在列表中的索引
//此函数非常的慢!
PGAMECROSS GetSessionPtrByAccount(LPCSTR sAccount, PINT_PTR lpIndex = NULL);
// 给连接到指定公共服务器的逻辑服务器广播消息
INT_PTR SendGroupLogicClientMsg(const int nCommServerId, LPVOID data, const SIZE_T nSize);
//向所有客户端送消息,消息将被立刻追加到客户端发的发送缓冲中。数据包必须是完成的格式(包含包头和包尾)
//参数eServerType表示服务器类型InvalidServer表示向所有类型的服务器发送否则向类型为eServerType的所有服务器发送
INT_PTR SendMsg2AllClient(const SERVERTYPE eServerType, LPCSTR sMsg, const size_t dwSize);
//向指定ID的逻辑户端发送消息消息将被立刻追加到客户端发的发送缓冲中。数据包必须是完成的格式包含包头和包尾
INT_PTR SendMsg2LogicClient(const INT_PTR nServerIndex, LPCSTR sMsg, const size_t dwSize);
//获取会话指针如果lpIndex参数非空则会向指针指向的内存填充值为会话在列表中的索引
PGAMECROSS GetSessionPtr(const unsigned int nSessionId,PINT_PTR lpIndex = NULL,Uint64 lKey= (Uint64)-1,int nServerIndex =-1);
CCrossServer(CCrossServerManager *lpSSManager);
~CCrossServer();
//向所有服务器投递消息,消息将在逻辑循环中被发送而不是立即发送。数据包必须是完成的格式(包含包头和包尾)
//参数eServerType表示服务器类型stInvalid表示向所有类型的服务器发送否则向类型为eServerType的所有服务器发送
VOID PostAllClientMsg(const SERVERTYPE eServerType, LPCSTR sMsg);
//获取会话数据如果会话存在则返回TRUE并为pSession填充会话数据内容
BOOL GetSession(const INT_PTR nSessionId,OUT PGAMECROSS pSession,int nServerIndex =-1);
//查找某个特定服会话的指针
PGAMECROSS GetSpecialServerSession(const INT_PTR nSessionId, const int nServerIndex);
//踢掉在线的用户
VOID PostKickCrossActor(const INT_PTR nSessionId, const int nServerIndex);
//处理剔除跨服用户
void ProcessKickCrossActor(const unsigned int nSessionId, const int nServerIndex);
//获取1个ip登陆的个数
int GetLoginAccountCount(LONGLONG lIp);
//获取当前全局会话数量
inline INT_PTR GetSessionCount(){ return m_SessionList.count(); }
//获取已经连接的逻辑服务器客户端数量如果nServerIndex参数为0则统计所有逻辑客户端数量
INT_PTR GetLogicClientCount(const INT_PTR nServerIndex);
//判断用户是否可以登录到目的服务器返回0表示可以登录。如果服务器的会话客户端未连接则返回-1如果服务器人员已满则返回-2,
INT_PTR UserCanLoginToServer(const INT_PTR nServerIndex);
//投递开启新会话的消息
BOOL PostOpenSession(const INT_PTR nServerIndex, // 登录的逻辑服务器ID
const INT_PTR nRawServerIndex, // 原始的服务器ID
LPCSTR sAccount, // 登录用户名
const unsigned int nSessionId, // 会话ID账号ID
const INT_PTR nIPAddr, // 登录IP地址
const INT_PTR dwTodayOnlineSec, // 今天在线时间
INT_PTR nGmLevel, // GM等级
UINT64 lKey , // 在逻辑服的key
INT_PTR nGateIndex, //在网关的编号 ,
bool bIsWhiteLogin, // 是否是白名单登陆的
bool bCommonMsg=false //是否中心会话服转发过来的消息
);
//投递按账号字符串关闭会话的消息,用于管理用
VOID PostCloseSessionByAccount(const LPCSTR sAccount);
//关闭一个会话
VOID PostCloseSessionByAccountId(Uint64 nAccountId,UINT64 lKey);
//遍历所有的连接,lpFn是毁掉函数指针lpParam是穿透参数会传递给对调函数。
VOID EnumConnections(EnumConnectionFn lpFn, LPCVOID lpParam);
CCrossServerManager* GetCSManager() { return m_pCSManager; }
//从会话中心服回来的跨平台请求结果
void OnSendPlatformResultToClient(int nServerIndex,CDataPacketReader &inPacket);
private:
CQueueList<PGAMECROSS> m_SessionList; //会话列表
CCSLock m_SessionListLock; //会话列表锁
CCrossServerManager* m_pCSManager; //所属会话管理器
INT_PTR m_nEngineClientCount;//引擎客户端数量
TICKCOUNT m_dwCheckOnlineLogTick;//下次检查记录在线人数的时间
BOOL m_boOnlineLoged; //是否已经记录在线人数
};
#endif//_CROSS_SERVER_H_

View File

@@ -0,0 +1,47 @@
#include "StdAfx.h"
CCrossServerManager::CCrossServerManager() {
m_sServerName[0] = 0;
m_pCrossServer = new CCrossServer(this);
}
CCrossServerManager::~CCrossServerManager() {
Shutdown();
SafeDelete(m_pCrossServer);
}
VOID CCrossServerManager::SetServerName(LPCSTR sSrvName) {
_asncpytA(m_sServerName, sSrvName);
}
VOID CCrossServerManager::SetCrossServiceAddress(LPCTSTR sHost, const int nPort) {
m_pCrossServer->SetServiceHost(sHost);
m_pCrossServer->SetServicePort(nPort);
}
BOOL CCrossServerManager::Startup() {
//初始化网络套接字
int nError = CCustomWorkSocket::InitSocketLib();
if ( nError ) {
OutputError( nError, _T("初始化网络库失败") );
return FALSE;
}
//启动会话客户端
if ( !m_pCrossServer->Startup() ) {
OutputMsg(rmError, _T("!m_pCrossServer->Startup() 失败"));
return FALSE;
}
return TRUE;
}
VOID CCrossServerManager::Shutdown()
{
//停止会话客户端
if( m_pCrossServer ) {
m_pCrossServer->Stop();
}
SafeDelete(m_pCrossServer);
}

View File

@@ -0,0 +1,48 @@
#ifndef _CROSSSSERVER_MANAGER_H_
#define _CROSSSSERVER_MANAGER_H_
/*****************************************************************
            Copyright (c) 2021, 上海漫方网络科技有限公司
                    All rights reserved
       
    创建日期  2021年04月28日 14时01分
    文件名称  CrossServer.h
    说    明:  跨服引擎管理类
    
    当前版本  1.00
    作    者:  
    概    述:  跨服引擎管理类
*****************************************************************/
class CSSGateManager;
class LogSender;
class CCrossServerManager
{
public:
CCrossServerManager();
~CCrossServerManager();
inline LPCSTR getServerName(){ return m_sServerName; };
inline CCrossServer* getCrossServer(){ return m_pCrossServer; };
//
inline VOID PostCrossServerMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4)
{
return m_pCrossServer->PostInternalMessage(uMsg, uParam1, uParam2, uParam3, uParam4);
}
//设置服务器名称
VOID SetServerName(LPCSTR sSrvName);
//设置跨服服务器地址和端口
VOID SetCrossServiceAddress(LPCTSTR sHost, const int nPort);
BOOL Startup();
VOID Shutdown();
private:
CHAR m_sServerName[128]; //服务器名称
CCrossServer* m_pCrossServer;//
};
#endif