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

📄 servertable.cpp

📁 Agent in c++ for DragonRaja
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// -------------------------------
// New Server Table
//
// Rewrote By chan78 at 2000/12/27
// -------------------------------

#define _WIN32_WINNT 0x0500

// Added by chan78 at 2001/07/16 :: include windows.h for WriteConsoleInput()
//#include <windows.h>

#include "servertable.h"
#include "servertable2.h"

// Added by chan78 at 2001/07/16 :: hIn.
extern HANDLE hIn;

CServerTable* g_pServerTable;

char ServerStatusSymbols[NUM_OF_SERVER_STATUS] =
{
	{' '},	// STATUS_NOT_IN_NETWORK
	{'T'},	// STATUS_TRYING_TO_CONNECT
	{'P'},	// STATUS_AWAITING_PROXY_CONNECTION
	{'C'},	// STATUS_SERVER_LIST_CERTIFIED
	{'1'},	// STATUS_AWAITING_SERVER_LIST
	{'2'},  // STATUS_AWAITING_SET_SERVER_LIST_RESULT
	{'3'},	// STATUS_AWAITING_CONNECTION_ORDER
	{'4'},	// STATUS_AWAITING_CONNECTION_RESULT
	{'5'},	// STATUS_AWAITING_DB_DEMON_SETTING
	{'6'},	// STATUS_AWAITING_SET_DB_DEMON_RESULT
	{'O'},	// STATUS_ACTIVATED
	{'-'},	// STATUS_INACTIVATED
	{'X'},	// STATUS_CLOSING
	{'R'},	// STATUS_RELOAD_GAMESERVER_DATA			//Added by KBS 020120
	{'O'}	// STATUS_FINISH_RELOAD_GAMESERVER_DATA		//Added by KBS 020120
};

//010221 KHS  
BYTE szMsg[MM_MAX_PACKET_SIZE+1+4];

// -----------------------------------------------------------------
// Constructor / Destructor
// -----------------------------------------------------------------
CServerTable::CServerTable( char* sFileName, WORD wMaxBucketNum, I4DyuchiNET* pINet )
{
	this->m_wMaxBucketNum = wMaxBucketNum;

	this->m_bIsServerRunning = true;
	this->m_dwNumOfServerConnections = 0;
	this->m_dwNumOfConnectedServers = 0;
	this->m_dwNumOfUsersInServerSet = 0;
	this->m_dwNumOfServers = 0;
	this->m_dwNumOfUsers = 0;

	for( DWORD i = 0; i < NUM_OF_SERVER_TYPES; i++ )
	{
		this->m_dwNumOfTypedServers[i] = 0;
	}

	this->m_pOwnDBDemonData = NULL;
	this->m_pOwnProxyServerData[PRIMARY_SERVER] = NULL;
	this->m_pOwnProxyServerData[SECONDARY_SERVER] = NULL;
	this->m_pOwnServerData = NULL;

	this->m_ppPackedTable = NULL;

	this->m_pServerListHead = NULL;
	this->m_pServerListTail = NULL;

	this->m_pINet = pINet;

	memset( this->m_szNewMsg, 0, MM_MAX_PACKET_SIZE );

	this->m_ppServerTable = new LP_HASHED_SERVER_DATA[this->m_wMaxBucketNum];
	memset(this->m_ppServerTable, 0, sizeof(LP_HASHED_SERVER_DATA)*this->m_wMaxBucketNum);

	this->m_ppPackedTable = new CPackedMsg*[this->m_wMaxBucketNum];
	memset(this->m_ppPackedTable, 0, m_wMaxBucketNum * sizeof(CPackedMsg*));

	// Added by chan78 at 2001/04/11
	this->m_ConnectionResultData.dwConnectionType = CONNECT_TYPE_NONE;
	this->m_ConnectionResultData.dwResultCheckedServers = 0;
	this->m_ConnectionResultData.dwToConnectServers = 0;
	this->m_ConnectionResultData.pSender = NULL;

	InitializeCriticalSection( &m_IsRunningCriticalSection );

#ifdef __IS_PROXY_SERVER
	memset( m_bConnectionStatus, 0, (MAX_SERVER_NUM*MAX_SERVER_NUM*sizeof(BYTE)) );
	InitializeCriticalSection( &m_IsUserAcceptAllowedCriticalSection );

	m_bIsUserAcceptAllowed = false;
#endif

	// Initialize
	this->InitServerTable( sFileName );

	return;
}

CServerTable::~CServerTable()
{
	// Remove OwnServerInfo
	if (this->m_pOwnServerData)
	{
		delete this->m_pOwnServerData;
		this->m_pOwnServerData = NULL;
	}
	
	// Remove PackedMsg Table
	if (this->m_ppPackedTable)
	{
		for ( DWORD i=0; i < this->m_dwNumOfTypedServers[SERVER_TYPE_AGENT]; i++)
		{
			delete this->m_ppPackedTable[i];
			this->m_ppPackedTable[i] = NULL;
		}
		delete this->m_ppPackedTable;
		this->m_ppPackedTable = NULL;
	}

	// Remove All ServerDatas In List
	this->RemoveAllServerDatasFromList();

	// Remove All HashedServerDatas In HashTable
	this->RemoveAllServerDatasFromTable();

	// Remove Server Table
	if ( this->m_ppServerTable )
	{
		delete [] this->m_ppServerTable;
		this->m_ppServerTable = NULL;
	}

	// Delete Critical Section
	DeleteCriticalSection( &m_IsRunningCriticalSection );

#ifdef __IS_PROXY_SERVER
	DeleteCriticalSection( &m_IsUserAcceptAllowedCriticalSection );
#endif

	return;
}


// -----------------------------------------------------------------
// Private Methods
// -----------------------------------------------------------------
void CServerTable::RemoveAllServerDatasFromTable()
{
	LP_HASHED_SERVER_DATA pCur = NULL;
	LP_HASHED_SERVER_DATA pNext = NULL;

	for ( WORD wIndex = 0; wIndex < this->m_wMaxBucketNum; wIndex++ )
	{
		pCur = this->m_ppServerTable[wIndex];
		while ( pCur )
		{
			pNext = pCur->pNextHashedServerData;
			delete pCur;
			pCur = pNext;
		}
		this->m_ppServerTable[wIndex] = NULL;
	}
	return;
}

void CServerTable::RemoveAllServerDatasFromList()
{
	LP_SERVER_DATA pCur = this->m_pServerListHead;
	LP_SERVER_DATA pNext = NULL;
	LP_HASHED_SERVER_DATA pDummy = NULL;

	while ( pCur )
	{
		pNext = pCur->pNextServerData;
		delete pCur;
		pCur = pNext;
	}
	return;
}

#ifdef __IS_PROXY_SERVER
DWORD CServerTable::BatchConnect()
{
	LP_AWAITING_CONNECTION_RESULT_DATA pResult = this->GetConnectionResultData();
	LP_SERVER_DATA pToConnectServer;

	// Added by chan78 at 2001/03/16 :: this->m_ConnectionResultData 啊 荤侩吝老订 公矫.
	// 捞繁 惑炔篮 缴阿窍促. 惯积秦急 救凳.
	if( pResult->dwConnectionType != CONNECT_TYPE_NONE )
	{
		MyLog( LOG_FATAL, "BatchConnect() :: this->m_ConnectionResultData is Already Using!!!(%d)", this->GetConnectionResultData()->dwConnectionType );
#ifdef __ON_DEBUG
		_asm int 3;
#else
		this->DestroyServer( FINISH_TYPE_UNKNOWN_ERROR );
#endif
	}
	pResult->dwConnectionType = CONNECT_TYPE_BATCH;
	pResult->dwToConnectServers = 0;
	pResult->dwResultCheckedServers = 0;
	pResult->pSender = NULL;

	// 2001/03/14
	for( pToConnectServer = this->m_pServerListHead; pToConnectServer; pToConnectServer = pToConnectServer->pNextServerData )
	{
		if( !this->ConnectToServer( pToConnectServer, CONNECT_TYPE_BATCH ) )
		{
			// 缴阿. 辑滚 磷牢促.
			MyLog( LOG_FATAL, "INETWORK::ConnectToServer() returned NULL!!!(port:%d)", pToConnectServer->wPort );
			this->DestroyServer( FINISH_TYPE_UNKNOWN_ERROR );
			return 0;
		}

		// 立加搬苞 贸府绰 妮归窃荐俊辑.
		pResult->dwToConnectServers++;
	}

	return pResult->dwToConnectServers;
}
#endif

void CServerTable::NotifyServerStatus()
{
	register char szDummy[16];
	LP_SERVER_DATA pDummyServerData;
	LP_NOTIFY_SERVER_STATUS_PACKET pPacket = (LP_NOTIFY_SERVER_STATUS_PACKET)(szDummy+1);
	DWORD dwFailCounter = 0;

	// BuildPacket
	szDummy[0] = PTCL_NOTIFY_SERVER_STATUS;
	pPacket->dwServerStatus = this->GetOwnServerData()->dwStatus;

	for( pDummyServerData = this->GetServerListHead(); pDummyServerData; pDummyServerData = pDummyServerData->pNextServerData )
	{
		if( pDummyServerData->dwConnectionIndex )
		{
			if( !this->Send( pDummyServerData->dwConnectionIndex, szDummy, sizeof(BYTE)+sizeof(NOTIFY_SERVER_STATUS_PACKET) ) )
			{
				dwFailCounter++;
			}
		}
	}
	if( dwFailCounter )
	{
		MyLog( LOG_IMPORTANT, "NotifyServerStatus :: %d Servers are can't receive Packet", dwFailCounter );
	}
	return;
}

bool CServerTable::NotifyServerStatus( LP_SERVER_DATA pToServer )
{
	register char szDummy[16];
	LP_NOTIFY_SERVER_STATUS_PACKET pPacket = (LP_NOTIFY_SERVER_STATUS_PACKET)(szDummy+1);

	// BuildPacket
	szDummy[0] = PTCL_NOTIFY_SERVER_STATUS;
	pPacket->dwServerStatus = this->GetOwnServerData()->dwStatus;

	if( !pToServer || !pToServer->dwConnectionIndex )
		return false;

	return this->Send( pToServer->dwConnectionIndex, szDummy, sizeof(BYTE)+sizeof(NOTIFY_SERVER_STATUS_PACKET) );
}


bool CServerTable::ReportServerStatus()
{
	if( this->GetOwnProxyServerData() )
	{
		return this->ReportServerStatus( this->GetOwnProxyServerData() );
	}
	else return false;
}

bool CServerTable::ReportServerStatus( LP_SERVER_DATA pToServer )
{
	register char szDummy[16];
	LP_REPORT_SERVER_STATUS_PACKET pAnswerPacket = (LP_REPORT_SERVER_STATUS_PACKET)(szDummy+1);

	szDummy[0] = PTCL_REPORT_SERVER_STATUS;

	pAnswerPacket->dwServerStatus = this->GetServerStatus();
	pAnswerPacket->dwNumOfUsers = this->m_dwNumOfUsers;

	if( !this->Send( pToServer->dwConnectionIndex, szDummy, sizeof(BYTE)+sizeof(REPORT_SERVER_STATUS_PACKET) ) )
	{
		MyLog( LOG_IMPORTANT, "Failed To Answer PTCL_ORDER_TO_REPORT_SERVER_STATUS to %s(%d)", GetTypedServerText(pToServer->dwServerType), pToServer->wPort );
		return false;
	}
	return true;
}

// -----------------------------------------------------------------
// Public Methods
// -----------------------------------------------------------------
void CServerTable::ShowServerStatus()
{

	LP_SERVER_DATA pCur = this->GetServerListHead();
	LP_SERVER_DATA pBefore = NULL;

	DWORD dwCount = 0;
	DWORD dwTurn = 0;

	MyLog( LOG_JUST_DISPLAY, "__________________________________________________________________________________" );
	MyLog( LOG_JUST_DISPLAY, "( )_NotInNetwork________(O)_Activated___________________(-)_InActivated___________" );
	MyLog( LOG_JUST_DISPLAY, "(P)_Awaiting PROXY Conn_(C)_Awaiting ServerList Certify_(1-6)_Being Negotiation___" );



	m_dwNumOfUsersInServerSet = 0;
	while( pCur )
	{
		dwCount++;

		dwTurn = (dwCount % 2);

		if( !dwTurn )
		{
#ifdef __IS_PROXY_SERVER

			MyLog( LOG_JUST_DISPLAY, "[%12s/%15s/%4d/(%c)(%4d)]      [%12s/%15s/%4d/(%c)(%4d)]"
			, GetTypedServerText( pBefore->dwServerType )
			, pBefore->szIP, pBefore->wPort, ServerStatusSymbols[pBefore->dwStatus] , pBefore->dwNumOfUsers 

			, GetTypedServerText( pCur->dwServerType )
			, pCur->szIP, pCur->wPort, ServerStatusSymbols[pCur->dwStatus],				pCur->dwNumOfUsers );
#else 

			MyLog( LOG_JUST_DISPLAY, "[%12s/%15s/%4d/(%c)]      [%12s/%15s/%4d/(%c)]"
			, GetTypedServerText( pBefore->dwServerType )
			, pBefore->szIP, pBefore->wPort, ServerStatusSymbols[pBefore->dwStatus]

			, GetTypedServerText( pCur->dwServerType )
			, pCur->szIP, pCur->wPort, ServerStatusSymbols[pCur->dwStatus]);
#endif
			if( pCur->dwServerType == SERVER_TYPE_AGENT ) m_dwNumOfUsersInServerSet += pCur->dwNumOfUsers ;
			if( pBefore->dwServerType == SERVER_TYPE_AGENT ) m_dwNumOfUsersInServerSet += pBefore->dwNumOfUsers ;
		}

		pBefore = pCur;
		pCur = pCur->pNextServerData;
	}

	if( dwTurn )
	{
#ifdef __IS_PROXY_SERVER
		MyLog( LOG_JUST_DISPLAY, "[%12s/%15s/%4d/(%c)(%4d)]"
		, GetTypedServerText( pBefore->dwServerType ), pBefore->szIP, pBefore->wPort, ServerStatusSymbols[pBefore->dwStatus], pBefore->dwNumOfUsers  );
#else
		MyLog( LOG_JUST_DISPLAY, "[%12s/%15s/%4d/(%c)]"
		, GetTypedServerText( pBefore->dwServerType ), pBefore->szIP, pBefore->wPort, ServerStatusSymbols[pBefore->dwStatus] );
#endif

		if( pBefore->dwServerType == SERVER_TYPE_AGENT ) m_dwNumOfUsersInServerSet += pBefore->dwNumOfUsers ;
	}


#ifdef __IS_PROXY_SERVER
	MyLog( LOG_JUST_DISPLAY, "Total %d Servers are listed(%d Connected)( %d ConcurUsers ).", this->GetNumOfServers(), this->GetNumOfConnectedServers(), m_dwNumOfUsersInServerSet);
#else
	MyLog( LOG_JUST_DISPLAY, "Total %d Servers are listed(%d Connected)", this->GetNumOfServers(), this->GetNumOfConnectedServers()  );
#endif

#ifdef __IS_MAP_SERVER
	// 010322 KHS
	extern char MapName[ MAX_PATH];	
	extern int NPC_COUNT;
	extern int ITEM_COUNT;
	MyLog( LOG_JUST_DISPLAY, "Server Info  [     %s    ] - Users: %d. Items: %d.  NPCs: %d.", MapName, this->GetNumOfUsers(), ITEM_COUNT, NPC_COUNT );
	MyLog( LOG_JUST_DISPLAY, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
	                          
#endif 
#ifdef __IS_AGENT_SERVER
	MyLog( LOG_JUST_DISPLAY, "Server Info  AGENT SERVER(%d) - Total (%d) Users are connected.", this->GetOwnServerData()->wPort, this->GetNumOfUsers() );
	MyLog( LOG_JUST_DISPLAY, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );

#endif

	return;

}

void CServerTable::SendPackedMsg()
{
	CPackedMsg* pPack = NULL;

	for (DWORD i=0; i < this->m_dwNumOfTypedServers[SERVER_TYPE_AGENT]; i++)
	{
		pPack = this->m_ppPackedTable[i];
		if ( pPack->GetUserNum() )
		{
			this->m_pINet->SendToServer( pPack->GetConnectionIndex(), (char*)pPack, pPack->GetPacketSize(), FLAG_SEND_NOT_ENCRYPTION );
			pPack->Release();
		}
	}
	return;
}

// To set OWN Server Status
void CServerTable::SetServerStatus( DWORD dwStatus )
{
	this->m_pOwnServerData->dwStatus = dwStatus;

	// ServerStatus 函版 舅覆.
	this->NotifyServerStatus();
	return;
}


// To set OTHER Server Status
void CServerTable::SetServerStatus( LP_SERVER_DATA pServerData, DWORD dwStatus )
{
	pServerData->dwStatus = dwStatus;
	return;
}

// Must be Thread-Safe
void CServerTable::DestroyServer( DWORD dwFinishType )
{
	// PROXY俊 舅赴促.
	char szDummy[1+4];
	szDummy[0] = (BYTE)PTCL_REPORT_SERVER_DESTROY;
	memcpy( szDummy+1, &dwFinishType, sizeof(DWORD) );

	if( this->GetOwnServerData() )

⌨️ 快捷键说明

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