#include #include #ifdef WIN32 #include #include #endif #include <_ast.h> #include <_memchk.h> #include #include #include #include #include #include "ShareUtil.h" #include "BufferAllocator.h" #include "AppItnMsg.h" #include "DataPacket.hpp" #include "CommonDef.h" #include "ServerDef.h" #include "SendPackPool.h" #include "CustomWorkSocket.h" #include "CustomServerClientSocket.h" #include "CustomClientSocket.h" #include "CustomJXClientSocket.h" #include "CustomJXServerClientSocket.h" #include "InterServerComm.h" //#include "../encrypt/CRC.h" //#include "../encrypt/Encrypt.h" //#include "../dataProcess/NetworkDataHandler.h" #include "CustomJXClientSocket.h" #include "CustomGlobalSession.h" #include "CustomSessionClient.h" using namespace jxSrvDef; using namespace jxInterSrvComm; const CCustomSessionClient::OnHandleSockPacket CCustomSessionClient::SSSockPacketHandlers[] = { &CCustomSessionClient::CatchDefaultPacket, &CCustomSessionClient::CatchOpenSession, &CCustomSessionClient::CatchCloseSession, &CCustomSessionClient::CatchUpdateSession, &CCustomSessionClient::CatchQuerySessionExists, }; CCustomSessionClient::CCustomSessionClient() :Inherited() { SetClientName(_T("会话")); } CCustomSessionClient::~CCustomSessionClient() { } VOID CCustomSessionClient::OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket) { if ( nCmd >= ArrayCount(SSSockPacketHandlers) ) { OutputMsg(rmWaning, _T("SessionServer[%s:%d]has sent invalid packet(%d),datalen:%d"), GetServerHost(), GetServerPort(), nCmd, inPacket.getLength()); } else { (this->*SSSockPacketHandlers[nCmd])(inPacket); } } VOID CCustomSessionClient::CatchDefaultPacket(CDataPacketReader &inPacket) { } VOID CCustomSessionClient::CatchOpenSession(CDataPacketReader &inPacket) { BOOL boNewSession = FALSE; GLOBALSESSIONOPENDATA SessionData; inPacket >> SessionData; OutputMsg(rmTip,"%s sessionid=%d",__FUNCTION__,SessionData.nSessionId); if ( SessionData.nSessionId && SessionData.sAccount[0] ) { CCustomGlobalSession* pSession = GetSessionPtr(SessionData.nSessionId, NULL,SessionData.lKey); if ( !pSession ) { pSession = CreateSession(); //填充会话基本数据 pSession->nSessionId = SessionData.nSessionId; pSession->nServerIndex = SessionData.nServerIndex; pSession->nRawServerId = SessionData.nRawServerId; pSession->nClientIPAddr = SessionData.nClientIPAddr; pSession->dwSessionTick = _getTickCount(); pSession->nState = SessionData.eState; pSession->dwFCMOnlineSec = SessionData.dwFCMOnlineSec; pSession->nGmLevel = SessionData.nGmLevel; //账户的GM等级 _asncpytA(pSession->sAccount, SessionData.sAccount); pSession->lKey = SessionData.lKey; pSession->nGateIndex = SessionData.nGateIndex; //将会话添加到全局会话队列中 m_SessionLock.Lock(); m_SessionList.add(pSession); m_SessionLock.Unlock(); boNewSession = TRUE; //test //OutputMsg(rmTip,"CustomSeesionClient Open Session,nSessionId=%d,nServerIndex=%d", // pSession->nSessionId,pSession->nServerIndex); } else { //设置成新的值 pSession->nSessionId = SessionData.nSessionId; pSession->nServerIndex = SessionData.nServerIndex; pSession->nRawServerId = SessionData.nRawServerId; pSession->nClientIPAddr = SessionData.nClientIPAddr; pSession->dwSessionTick = _getTickCount(); pSession->nState = SessionData.eState; pSession->dwFCMOnlineSec = SessionData.dwFCMOnlineSec; pSession->nGmLevel = SessionData.nGmLevel; _asncpytA(pSession->sAccount, SessionData.sAccount); pSession->lKey = SessionData.lKey; pSession->nGateIndex = SessionData.nGateIndex; } OnOpenSession(pSession, boNewSession); } } VOID CCustomSessionClient::CatchCloseSession(CDataPacketReader &inPacket) { int nSessionId; UINT64 lKey =0; //玩家的key inPacket >> nSessionId >>lKey ;//<<----从通信数据包中获取全局会话ID OutputMsg(rmTip,"%s sessionid=%d",__FUNCTION__,nSessionId); INT_PTR nIdx; CCustomGlobalSession *pSession = GetSessionPtr(nSessionId, &nIdx,lKey); if ( pSession ) { //调用会话删除的通知函数 OnCloseSession(pSession); //test //OutputMsg(rmTip,"CustomSeesionClient Close Session,nSessionId=%d,nServerIndex=%d", // pSession->nSessionId,pSession->nServerIndex); m_SessionList.remove(nIdx); DestroySession(pSession); } else { OutputMsg(rmTip,"CatchCloseSession id=%d, pSession is NULL",nSessionId); } } VOID CCustomSessionClient::CatchUpdateSession(CDataPacketReader &inPacket) { int nSessionId = 0; GSSTATE nNewState = gsSelChar; UINT64 lKey =0; inPacket >> nSessionId;//<<----从通信数据包中获取全局会话ID inPacket >> nNewState;//<----从通信数据包中获取会话的状态值 inPacket >> lKey;//<---- CCustomGlobalSession *pSession = GetSessionPtr( nSessionId, NULL,lKey ); if ( pSession ) { GSSTATE nOldState = pSession->nState; pSession->nState = nNewState; //调用关于会话状态变更的通知函数 OnUpdateSessionState(pSession, nOldState, nNewState); } } VOID CCustomSessionClient::CatchQuerySessionExists(CDataPacketReader &inPacket) { int nSessionId = 0; inPacket >> nSessionId;//<<----从通信数据包中获取全局会话ID //调用查询会话是否在线的函数 OnQuerySessionExists(nSessionId); } /* void CCustomSessionClient::SendKeepAlive() { #pragma __CPMSG__(发送保持连接的心跳包) //flushProtoPacket(allocProtoPacket(??)); } */ CCustomGlobalSession* CCustomSessionClient::GetSessionPtr(const INT_PTR nSessionID, PINT_PTR pIndex,UINT64 lKey) { INT_PTR i; CCustomGlobalSession **pSessionList; pSessionList = m_SessionList; for (i=m_SessionList.count()-1; i>-1; --i) { if ( pSessionList[i]->nSessionId == nSessionID && pSessionList[i]->lKey == lKey) { if (pIndex) *pIndex = i; return pSessionList[i]; } } return NULL; } VOID CCustomSessionClient::ClearSessionList() { INT_PTR i; CCustomGlobalSession **pSessionList; CSafeLock sl(&m_SessionLock); pSessionList = m_SessionList; for (i=m_SessionList.count()-1; i>-1; --i) { if ( pSessionList[i] ) { DestroySession(pSessionList[i]); } } m_SessionList.clear(); } VOID CCustomSessionClient::DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4) { CCustomGlobalSession *pSession; WORD cmd = 0; switch(uMsg) { case SSIM_RESULT_SESSION_EXISTS: cmd = jxInterSrvComm::SessionServerProto::cQueryResult; break; case SSIM_CHG_SESSION_STATE: cmd = jxInterSrvComm::SessionServerProto::cUpdateSession ; break; case SSIM_CLOSE_SESSION: cmd = jxInterSrvComm::SessionServerProto::cCloseSession ; break; default: return; } CDataPacket &data = allocProtoPacket(cmd); //分配一个 网络包 switch (uMsg) { case SSIM_RESULT_SESSION_EXISTS://返回查询会话是否在线的结果 uParam1=全局会话ID,uParam2=在线?1:0 { //返回会话服务器用户是否存在 data << (int) uParam1; data << (BYTE) uParam2; break; } case SSIM_CHG_SESSION_STATE://改变会话状态 uParam1=全局会话ID,uParam2=会话状态,值为GSSTATE的枚举值 { pSession = GetSessionPtr(uParam1, NULL,uParam3); if ( pSession ) { pSession->nState = (GSSTATE)uParam2; //向会话服务器发送改变会话状态的消息 data << (int) uParam1; data << (int) uParam2; } else { OutputMsg(rmWaning,_T("SSIM_CHG_SESSION_STATE 改变会话的时候没有找到需要改变状态的会话%d\n"), (int)uParam1); } } break; case SSIM_CLOSE_SESSION://关闭会话 uParam1=全局会话ID { pSession = GetSessionPtr(uParam1, NULL,uParam2); if ( pSession ) { //如果会话的状态不是等待连接下一个服务器的状态则关闭会话 //if ( pSession->nState != gsWaitQueryChar && pSession->nState != gsWaitEntryGame ) data << (int) uParam1 << UINT64(uParam2); } else { data << (int) 0 << 0; OutputMsg(rmWaning,_T("SSIM_CLOSE_SESSION 没有找到需要关闭的会话%d\n"), (int)uParam1); } } break; } flushProtoPacket(data); } CCustomGlobalSession* CCustomSessionClient::CreateSession() { return (CCustomGlobalSession*)m_Allocator.AllocBuffer(sizeof(CCustomGlobalSession)); } VOID CCustomSessionClient::DestroySession(CCustomGlobalSession* pSession) { m_Allocator.FreeBuffer(pSession); } VOID CCustomSessionClient::OnWorkThreadStop() { ClearSessionList(); } bool CCustomSessionClient::GetSessionData(const int nSessionID,UINT64 lKey,OUT PGLOBALSESSIONOPENDATA pSessionData) { INT_PTR i; bool boResult = false; CCustomGlobalSession **pSessionList, *pSession; CSafeLock sl(&m_SessionLock); pSessionList = m_SessionList; for (i=m_SessionList.count()-1; i>-1; --i) { if ( pSessionList[i]->nSessionId == nSessionID && lKey== pSessionList[i]->lKey) { pSession = pSessionList[i]; //填充会话基本数据 pSessionData->nSessionId = (INT)pSession->nSessionId; pSessionData->nServerIndex = (INT)pSession->nServerIndex; pSessionData->nRawServerId = pSession->nRawServerId; pSessionData->nClientIPAddr = pSession->nClientIPAddr; pSessionData->dwFCMOnlineSec = pSession->dwFCMOnlineSec; pSessionData->eState = pSession->nState; pSessionData->nGmLevel = pSession->nGmLevel; //GM等级 _asncpytA(pSessionData->sAccount, pSession->sAccount); boResult = true; } } return boResult; } VOID CCustomSessionClient::OnConnected() { Inherited::OnConnected(); }