📄 servertable.cpp
字号:
// -------------------------------
// 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 + -