⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 authsocket.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
字号:
// AuthSocket.cc
/*/////////////////////////////////////////////////////////////////////////////

	李亦
	2006.06.
/*//////////////////////////////////////////////////////////////////////////////

//#include <platforms.h>
#include "platform/event.h"
#include "core/dataChunker.h"
#include "server/net/IOSocket.h"
#include "server/encrypt/EncryptEngine.h"
#include "server/net/AuthSocket.h"
#include "sim/netConnection.h"

namespace CS
{
//#include"config.h"

////////////////////////////////////////////////////////////////////////
//数据包缓冲池管理

#define PACKETQUEUE_INIT		1
#define PACKETQUEUE_GROW		32


class PacketBufPoolHandle
{
	FreeListChunker<PacketBuffer>	gs_pkBufPool;
	MutexInstance						m_mutexPool;
	//PacketBufPoolHandle()
public:
	PacketBuffer* alloc() 
	{
		MutexHandle mutex(m_mutexPool,true);
		return gs_pkBufPool.alloc();
	}
	void free(PacketBuffer* pFree) 
	{
		MutexHandle mutex(m_mutexPool,true);
		return gs_pkBufPool.free(pFree);
	}
};

static PacketBufPoolHandle gs_pkBufPool;



//                                               //
////////// Authenticated Socket Class /////////////
//                                               //


CAuthSocket::CAuthSocket(CS_AUTHHANDLER *pHandler, CS_IOHANDLER *pIOH, CS_ENCRYPTHANDLER *pEE)
:m_queueRecv(PACKETQUEUE_INIT,PACKETQUEUE_GROW)
,m_queueSend(PACKETQUEUE_INIT,PACKETQUEUE_GROW)
{
	m_pAuthHandler		= pHandler;
	m_pIOHandler		= pIOH;
	m_pEncryptHandler	= pEE;

	m_pEncryptEngine	= NULL;
	m_pIOSock			= NULL;
	m_pData				= NULL;

	m_pConnection		= NULL;
	m_pPacketBufRecv	= NULL;
	m_pPacketBufSend	= NULL;
	m_ssQueueSend		= ASS_NULL;//默认为 TRUE
	m_ssQueueRecv		= ASS_NULL;

	m_dwWorkState		= 0;

	m_netGateway.SvrListenConnection(this);
}


CAuthSocket::~CAuthSocket()
{
	Close();
	//if(m_pEncryptEngine != NULL) 
	//	delete m_pEncryptEngine;
	//if(m_pIOSock != NULL) 
	//	delete m_pIOSock;
}


BOOL CAuthSocket::BeginSend(BitStream* pStream, BOOL bQueue,U8 uPacketType)
{
	AssertWarn(m_pPacketBufSend==0,"在调用BeginSend之前,需要调用SendOutPacket或EndSend(true),释放 m_pPacketBufSend ");

	if(pStream == NULL)
		return FALSE;

	U32	uSize		= MaxPacketDataSize;
	m_ssQueueSend	= bQueue?ASS_QUEUE : ASS_SINGLE;

	m_pPacketBufSend = gs_pkBufPool.alloc();
	if(m_pPacketBufSend == NULL)
		return FALSE;

	m_pPacketBufSend->uSize	= uSize;
	m_pPacketBufSend->uPacketType	= uPacketType;

	pStream->setBuffer(m_pPacketBufSend->szBuffer, uSize, MaxPacketDataSize);
	pStream->setPosition(0);

	//填充识别码,U8
	if(uPacketType != 0)
		pStream->write(uPacketType);

	return TRUE;
}


BOOL CAuthSocket::EndSend(BitStream* pStream, BOOL bProcessNow)
{
	AssertWarn(m_pPacketBufSend,"包缓冲区不能为NULL");
	if(pStream == NULL)
		return FALSE;

	if(m_pPacketBufSend == NULL)
		return FALSE;

	m_pPacketBufSend->uSize = pStream->getPosition();

	//在EndSend中加入,因为需要等Stream填满后,才加到队列处理
	//队列未满,则加到尾部
	//已满,则删除头1数据包,加到尾部,打开Push的always标志即可
	if(m_ssQueueSend == ASS_QUEUE)
	{
		m_mutexWorkState.lock(true);
		m_queueSend.Push(m_pPacketBufSend);
		m_mutexWorkState.unlock();
		m_pPacketBufSend = NULL;
	}

	if(bProcessNow)
		return SendOutPacket(m_ssQueueSend == ASS_QUEUE) == E_IOOK;

	return TRUE;
}





S32 CAuthSocket::SendOutPacket(BOOL bQueue)
{

	S32 nRet;

	if(!bQueue)
	{
		AssertWarn(m_pPacketBufSend,"包缓冲区不能为NULL");
		if(m_pPacketBufSend)
		{
			//if(IsAlive() && CheckSend(FALSE))
			nRet = Send(m_pPacketBufSend->szBuffer, m_pPacketBufSend->uSize);
			gs_pkBufPool.free(m_pPacketBufSend);
			m_pPacketBufSend	= NULL;
		}
		else
			nRet = E_IOFAILED;

		return nRet;
	}



	m_mutexWorkState.lock(true);
	PacketBuffer*  pPKBuf = m_queueSend.Shift();
	m_mutexWorkState.unlock();

	//发送到IOSocket
	if(pPKBuf)
	{
		//if(IsAlive() && CheckSend(FALSE))
		nRet = Send(pPKBuf->szBuffer, pPKBuf->uSize);
		gs_pkBufPool.free(pPKBuf);
	}
	else
		nRet = E_IOFAILED;

	return nRet;
}



BOOL CAuthSocket::BeginRecv(BOOL bQueue,U8 uPacketType)
{
	AssertWarn(m_pPacketBufRecv==0,"在调用BeginSend之前,需要调用ProcessRecvStream或EndRecv(true),释放 m_pPacketBufRecv ");

	//if(!IsAlive() || !CheckRecv(FALSE))
	//	return FALSE;

	U32 	uSize		= MaxPacketDataSize;
	m_ssQueueRecv	= bQueue?ASS_QUEUE : ASS_SINGLE;

	m_pPacketBufRecv = gs_pkBufPool.alloc();
	if(m_pPacketBufRecv == NULL)
		return FALSE;

	m_pPacketBufRecv->uSize			= uSize;
	m_pPacketBufRecv->uPacketType	= uPacketType;

	return TRUE;
}


BOOL CAuthSocket::EndRecv()
{
	AssertWarn(m_pPacketBufRecv,"包缓冲区不能为NULL");
	if(m_pPacketBufRecv == NULL )
		return FALSE;

	S32				nRet;
	PacketBuffer*  pPKBuf;
	U32				uSize;

	pPKBuf	= m_pPacketBufRecv;
	uSize		= pPKBuf->uSize;
	if(!uSize)
		uSize = MaxPacketDataSize;


	//接收到IOSocket
	//调整 IOTCPModule::Recv 接收模式
	nRet = Recv(pPKBuf->szBuffer,(int*)&uSize);
	if(nRet == E_IOOK)
		pPKBuf->uSize = uSize;
	else
		pPKBuf->uSize = E_IOFAILED;

	if(m_ssQueueRecv == ASS_QUEUE)
	{
		m_mutexWorkState.lock(true);
		m_queueRecv.Push(m_pPacketBufRecv);
		m_mutexWorkState.unlock();
		m_pPacketBufRecv = NULL;
	}

	return nRet == E_IOOK;
}




BOOL CAuthSocket::DispatchRecvStream(BitStream* pStream, BOOL bQueue)
{
   U8					uPacketType;
	S32				nRet;
	PacketBuffer*  pPKBuf;
	U32				uSize;

	AssertWarn(pStream,"Stream不能为NULL");
	if(pStream == NULL)
		return FALSE;

	if(bQueue)
	{
		m_mutexWorkState.lock(true);
		pPKBuf	= m_queueRecv.Shift();
		m_mutexWorkState.unlock();
	}
	else //
	{
		pPKBuf	= m_pPacketBufRecv;
	}


	if(pPKBuf == NULL)
		return FALSE;

	uSize		= pPKBuf->uSize;
	if(uSize != E_IOFAILED)
	{
		if(!uSize)
			uSize = MaxPacketDataSize;
		pStream->setBuffer(pPKBuf->szBuffer, uSize, MaxPacketDataSize);

		pStream->read(&uPacketType);
		AssertWarn(pPKBuf->uPacketType == uPacketType,"数据包识别码不吻合...");
		pPKBuf->uPacketType = uPacketType;

		ProcessRecvPackets(pStream,uPacketType);
	}

	gs_pkBufPool.free(pPKBuf);
	if(m_pPacketBufRecv != NULL)
		m_pPacketBufRecv = NULL;

	return uSize != E_IOFAILED;
}

BOOL CAuthSocket::ProcessRecvPackets(BitStream* pStream, U8 uPacketType)
{
	switch(uPacketType)
	{
	case PT_GAMENORMAL:
		AssertFatal(m_pConnection,"需要进行 attachConnection NetConnection接收发送数据,释放包缓存");
		m_pConnection->processRawPacket(pStream);
		break;
	default:
		return m_netGateway.ProcessRecvPackets(pStream, uPacketType);
		break;
	}
	return TRUE;
}


BOOL CAuthSocket::BlockRecvPacket(U8 uPacketType)
{
	if(BeginRecv(FALSE,uPacketType))
	{
		if(EndRecv())
		{	
			BitStream  stream(0,0);
			return DispatchRecvStream(&stream,FALSE);
		}
	}
	return FALSE;
}








int CAuthSocket::Listen(char *svTarget, int nUserId)
{
	m_pIOSock = new CIOSocket(m_pIOHandler);
	if(m_pIOSock != NULL) 
	{
		m_pEncryptEngine=new CEncryptionEngine(m_pEncryptHandler);
		if(m_pEncryptEngine != NULL) 
		{
			if(m_pIOSock->Listen(svTarget) == E_IOOK) 
			{
				if(m_pEncryptEngine->Startup() == E_IOOK) 
				{
					if(m_pAuthHandler->pOnListen == NULL) 
						return E_IOOK;

					m_pData = m_pAuthHandler->pOnListen(m_pIOSock, m_pEncryptEngine, nUserId);
					if(m_pData != NULL) 
						return E_IOOK;

					m_pEncryptEngine->Shutdown();
				}//if(m_pEncryptEngine->Startup() == 0) }

				m_pIOSock->Close();
			}//if(m_pIOSock->Listen(svTarget) == 0) 

			delete m_pEncryptEngine;
			m_pEncryptEngine=NULL;
		}//if(m_pEncryptEngine != NULL) 

		delete m_pIOSock;
		m_pIOSock=NULL;
	}//if(m_pIOSock != NULL) 

	return E_IOFAILED;
}


BOOL CAuthSocket::OnAcceptParam(CAuthSocket	*pAuthSockNew)
{
	if(pAuthSockNew == NULL)
		return FALSE;
	pAuthSockNew->m_netGateway.ServerBlockSequene();

	return TRUE;
}


BOOL CAuthSocket::OnConnectParam(void)
{
	AssertFatal(m_pConnection,"需要指定Connection对象");
	if(m_pConnection == NULL)
		return FALSE;

	m_netGateway.ClientBlockSequene();
	return TRUE;
}


int CAuthSocket::Connect(char *svTarget, int nUserId)
{
	m_pIOSock = new CIOSocket(m_pIOHandler);
	if(m_pIOSock != NULL) 
	{
		m_pEncryptEngine = new CEncryptionEngine(m_pEncryptHandler);
		if(m_pEncryptEngine != NULL)
		{
			if(m_pIOSock->Connect(svTarget) == E_IOOK) 
			{
				if(OnConnectParam())
				{
					if(m_pEncryptEngine->Startup() == E_IOOK)
					{
						if(m_pAuthHandler->pOnConnect == NULL) 
							return E_IOOK;
						//建立
						m_pData = m_pAuthHandler->pOnConnect(m_pIOSock, m_pEncryptEngine, nUserId);
						if(m_pData != NULL)
							return E_IOOK;

						m_pEncryptEngine->Shutdown();
					}//if(m_pEncryptEngine->Startup() == 0)

					m_pIOSock->Close();
				}
			}//if(m_pIOSock->Connect(svTarget) == 0) 

			delete m_pEncryptEngine;
			m_pEncryptEngine = NULL;
		}//if(m_pEncryptEngine != NULL)

		delete m_pIOSock;
		m_pIOSock = NULL;
	}//if(m_pIOSock != NULL) 
	return E_IOFAILED;

	return E_IOOK;
}


CAuthSocket *CAuthSocket::Accept(void)
{
	CIOSocket *pIOSockNew = m_pIOSock->Accept();
	if(pIOSockNew != NULL) 
	{
		CAuthSocket		*pAuthSockNew;
		pAuthSockNew	= new CAuthSocket(m_pAuthHandler, m_pIOHandler, m_pEncryptHandler);
		if(pAuthSockNew != NULL) 
		{
			pAuthSockNew->m_pIOSock			= pIOSockNew;
			pAuthSockNew->m_pEncryptEngine= new CEncryptionEngine(pAuthSockNew->m_pEncryptHandler);
			if(pAuthSockNew->m_pEncryptEngine != NULL) 
			{
				if(OnAcceptParam(pAuthSockNew) )
				{
					if(pAuthSockNew->m_pEncryptEngine->Startup() == E_IOOK) 
					{

						if(m_pAuthHandler->pOnAccept == NULL)
							return pAuthSockNew;

						pAuthSockNew->m_pData = m_pAuthHandler->pOnAccept(m_pData, 
																	pAuthSockNew->m_pIOSock,  
																	pAuthSockNew->m_pEncryptEngine);
						if(pAuthSockNew->m_pData != NULL) 
							return pAuthSockNew;
						
						pAuthSockNew->m_pEncryptEngine->Shutdown();
					}//if(pAuthSockNew->m_pEncryptEngine->Startup() == 0) 
				}

				delete pAuthSockNew->m_pEncryptEngine;
				pAuthSockNew->m_pEncryptEngine=NULL;
			}//if(pAuthSockNew->m_pEncryptEngine != NULL) 

			pAuthSockNew->m_pIOSock=NULL;
			delete pAuthSockNew;
		}//if(pAuthSockNew != NULL)

		pIOSockNew->Close();
		delete pIOSockNew;
	}//if(pIOSockNew != NULL) 

	return NULL;
}


int CAuthSocket::Close(void)
{
	if(IsKILLING())
		return E_IOOK;

	SetKILLING();

	if(m_pConnection)
	{	
		m_pConnection->closeConnection();
		m_pConnection = NULL;
	}

	if(m_pIOSock)
	{
		m_pIOSock->Close();
		delete m_pIOSock;
		m_pIOSock	= NULL;
	}

	if(m_pEncryptEngine)
	{
		m_pEncryptEngine->Shutdown();
		delete m_pEncryptEngine;
		m_pEncryptEngine = NULL;
	}

	if(m_pAuthHandler)
	{
		if(m_pAuthHandler->pOnClose && m_pData)
		m_pAuthHandler->pOnClose(m_pData);
		m_pAuthHandler = NULL;
	}



	m_pData			= NULL;

#ifdef TORQUE_DEBUG
	Con::printf("x 连接断开...");
#endif
	return E_IOOK;
}	


int CAuthSocket::Recv(BYTE *pBufRecv, int *pnInDataLen)
{
	int	nRet;

	nRet	= m_pIOSock->Recv(pBufRecv,pnInDataLen);
	//AssertFatal(0,"在此检测断线状态,如下面算法");

	if(nRet == E_IOOK) 
		return E_IOOK;

	if(nRet == E_IODISCONNECTED)
		SetTOBEDIE();
		
	//if(nRet != Net::WouldBlock)
	//	SetTOBEDIE();
	return nRet;

	//{	
	//	m_pIOSock->SaveError();
	//	if(m_pIOSock->HasError())
	//		m_pIOSock->SetKill(TRUE);
	//	return nRet;
	//}
	
	//if(m_pAuthHandler->pOnRecv(m_pData, m_pEncryptEngine, pBufRecv, nRecvLen, pInData, pnInDataLen) == -1) 
	//	nRet = -1;

	//return nRet;
}


int CAuthSocket::Send(BYTE *pData, int nDataLen)
{
	//BYTE *pOutData;
	int	/*nOutDataLen,*/
			nRet;

	//if(m_pAuthHandler->pOnSend(m_pData, m_pEncryptEngine, pData, nDataLen, &pOutData, &nOutDataLen) == -1)
	//	return E_IOFAILED;

	nRet = m_pIOSock->Send(pData, nDataLen);
	if(nRet == E_IOOK) 
		return E_IOOK;

	//if(nRet < 0) 
	{	
		//m_pIOSock->SaveError();
		//if(m_pIOSock->HasError())
		//	m_pIOSock->SetKill(TRUE);
	return nRet;
	}
	
	//m_pAuthHandler->pFree(m_pData, pOutData);
	//return nRet;

}


int CAuthSocket::RecvEx(BYTE **pInData, int *pnInDataLen)
{
	BYTE *pBufRecv;
	int	nRecvLen;
	int	nRet;

	nRet	= m_pIOSock->RecvEx(&pBufRecv,&nRecvLen);

	//AssertFatal(0,"在此检测断线状态,如下面算法,参考Recv");

	if(nRet != Net::OK)
	{
		if(nRet == E_IODISCONNECTED)
			SetTOBEDIE();
	//	if(nRet != Net::WouldBlock)
	//		SetTOBEDIE();
		return nRet;
	}



	//if(nRet !=  E_IOOK) 
	//{	
	//	m_pIOSock->SaveError();
	//	if(m_pIOSock->HasError())
	//		m_pIOSock->SetKill(TRUE);
	//	return nRet;
	//}
	
	if(m_pAuthHandler->pOnRecv(m_pData, m_pEncryptEngine, pBufRecv, nRecvLen, pInData, pnInDataLen) == E_IOFAILED) 
		nRet = E_IOFAILED;

	m_pIOSock->Free(pBufRecv);
	return nRet;
}


int CAuthSocket::SendEx(BYTE *pData, int nDataLen)
{
	BYTE *pOutData;
	int	nOutDataLen,
			nRet;

	if(m_pAuthHandler->pOnSend(m_pData, m_pEncryptEngine, pData, nDataLen, &pOutData, &nOutDataLen) == E_IOFAILED)
		return E_IOFAILED;

	nRet = m_pIOSock->SendEx(pOutData, nOutDataLen);
	if(nRet != E_IOOK) 
	{	
		//m_pIOSock->SaveError();
		//if(m_pIOSock->HasError())
		//	m_pIOSock->SetKill(TRUE);
		return nRet;
	}
	
	m_pAuthHandler->pFree(m_pData, pOutData);
	return E_IOOK;

}


void CAuthSocket::Free(BYTE *pBuffer)
{
	m_pAuthHandler->pFree(m_pData, pBuffer);
}


int CAuthSocket::GetUserID(void)
{
	return m_pAuthHandler->pGetUserID(m_pData);
}


CS_AUTHHANDLER *CAuthSocket::GetAuthHandler(void)
{
	return m_pAuthHandler;
}


int CAuthSocket::GetRemoteAddr(char *svAddr,int nMaxLen)
{
	return m_pIOSock->GetRemoteAddr(svAddr,nMaxLen);
}
	
int CAuthSocket::GetConnectAddr(char *svAddr, int nMaxLen)
{
	return m_pIOSock->GetConnectAddr(svAddr,nMaxLen);
}

void* CAuthSocket::GetNetAddress()
{
	return m_pIOSock->GetNetAddress();
}

};//namespace CS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -