2010-05-29 07:25:38 +00:00
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
# include <base/system.h>
# include <engine/shared/config.h>
# include <engine/shared/engine.h>
# include <engine/shared/protocol.h>
# include <engine/shared/snapshot.h>
# include <engine/shared/compression.h>
# include <engine/shared/network.h>
# include <engine/shared/config.h>
# include <engine/shared/packer.h>
# include <engine/shared/datafile.h>
2010-09-12 10:16:51 +00:00
# include <engine/shared/demo.h>
2010-05-29 07:25:38 +00:00
# include <engine/server.h>
# include <engine/map.h>
# include <engine/console.h>
# include <engine/storage.h>
# include <engine/masterserver.h>
# include <engine/config.h>
# include <mastersrv/mastersrv.h>
2010-07-29 05:21:18 +00:00
# include <string.h>
2010-05-29 07:25:38 +00:00
# include "register.h"
# include "server.h"
2010-08-22 16:06:20 +00:00
# if defined(CONF_FAMILY_WINDOWS)
2010-05-29 07:25:38 +00:00
# define _WIN32_WINNT 0x0500
# define NOGDI
# include <windows.h>
# endif
static const char * StrLtrim ( const char * pStr )
{
2010-08-12 14:12:25 +00:00
while ( * pStr & & * pStr > = 0 & & * pStr < = 32 )
2010-05-29 07:25:38 +00:00
pStr + + ;
return pStr ;
}
static void StrRtrim ( char * pStr )
{
int i = str_length ( pStr ) ;
while ( i > = 0 )
{
2010-08-12 14:12:25 +00:00
if ( pStr [ i ] < 0 | | pStr [ i ] > 32 )
2010-05-29 07:25:38 +00:00
break ;
pStr [ i ] = 0 ;
i - - ;
}
}
static int StrAllnum ( const char * pStr )
{
while ( * pStr )
{
if ( ! ( * pStr > = ' 0 ' & & * pStr < = ' 9 ' ) )
return 0 ;
pStr + + ;
}
return 1 ;
}
CSnapIDPool : : CSnapIDPool ( )
{
Reset ( ) ;
}
void CSnapIDPool : : Reset ( )
{
for ( int i = 0 ; i < MAX_IDS ; i + + )
{
m_aIDs [ i ] . m_Next = i + 1 ;
m_aIDs [ i ] . m_State = 0 ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_aIDs [ MAX_IDS - 1 ] . m_Next = - 1 ;
m_FirstFree = 0 ;
m_FirstTimed = - 1 ;
m_LastTimed = - 1 ;
m_Usage = 0 ;
m_InUsage = 0 ;
}
void CSnapIDPool : : RemoveFirstTimeout ( )
{
int NextTimed = m_aIDs [ m_FirstTimed ] . m_Next ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// add it to the free list
m_aIDs [ m_FirstTimed ] . m_Next = m_FirstFree ;
m_aIDs [ m_FirstTimed ] . m_State = 0 ;
m_FirstFree = m_FirstTimed ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// remove it from the timed list
m_FirstTimed = NextTimed ;
if ( m_FirstTimed = = - 1 )
m_LastTimed = - 1 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_Usage - - ;
}
int CSnapIDPool : : NewID ( )
{
int64 Now = time_get ( ) ;
// process timed ids
while ( m_FirstTimed ! = - 1 & & m_aIDs [ m_FirstTimed ] . m_Timeout < Now )
RemoveFirstTimeout ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
int Id = m_FirstFree ;
dbg_assert ( Id ! = - 1 , " id error " ) ;
m_FirstFree = m_aIDs [ m_FirstFree ] . m_Next ;
m_aIDs [ Id ] . m_State = 1 ;
m_Usage + + ;
m_InUsage + + ;
return Id ;
}
void CSnapIDPool : : TimeoutIDs ( )
{
// process timed ids
while ( m_FirstTimed ! = - 1 )
RemoveFirstTimeout ( ) ;
}
void CSnapIDPool : : FreeID ( int Id )
{
dbg_assert ( m_aIDs [ Id ] . m_State = = 1 , " id is not alloced " ) ;
m_InUsage - - ;
m_aIDs [ Id ] . m_State = 2 ;
m_aIDs [ Id ] . m_Timeout = time_get ( ) + time_freq ( ) * 5 ;
m_aIDs [ Id ] . m_Next = - 1 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( m_LastTimed ! = - 1 )
{
m_aIDs [ m_LastTimed ] . m_Next = Id ;
m_LastTimed = Id ;
}
else
{
m_FirstTimed = Id ;
m_LastTimed = Id ;
}
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
void CServer : : CClient : : Reset ( )
{
// reset input
for ( int i = 0 ; i < 200 ; i + + )
m_aInputs [ i ] . m_GameTick = - 1 ;
m_CurrentInput = 0 ;
mem_zero ( & m_LatestInput , sizeof ( m_LatestInput ) ) ;
m_Snapshots . PurgeAll ( ) ;
m_LastAckedSnapshot = - 1 ;
m_LastInputTick = - 1 ;
m_SnapRate = CClient : : SNAPRATE_INIT ;
m_Score = 0 ;
}
CServer : : CServer ( ) : m_DemoRecorder ( & m_SnapshotDelta )
{
m_TickSpeed = SERVER_TICK_SPEED ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_pGameServer = 0 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_CurrentGameTick = 0 ;
m_RunServer = 1 ;
mem_zero ( m_aBrowseinfoGametype , sizeof ( m_aBrowseinfoGametype ) ) ;
m_BrowseinfoProgression = - 1 ;
m_pCurrentMapData = 0 ;
m_CurrentMapSize = 0 ;
2010-08-22 16:06:20 +00:00
2010-05-30 12:01:11 +00:00
m_MapReload = 0 ;
2010-05-29 07:25:38 +00:00
2010-09-12 11:52:25 +00:00
m_RconClientId = - 1 ;
2010-05-29 07:25:38 +00:00
Init ( ) ;
}
int CServer : : TrySetClientName ( int ClientID , const char * pName )
{
char aTrimmedName [ 64 ] ;
// trim the name
str_copy ( aTrimmedName , StrLtrim ( pName ) , sizeof ( aTrimmedName ) ) ;
StrRtrim ( aTrimmedName ) ;
2010-08-17 22:06:00 +00:00
/*char aBuf[256];
str_format ( aBuf , sizeof ( aBuf ) , " '%s' -> '%s' " , pName , aTrimmedName ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ; */
2010-05-29 07:25:38 +00:00
pName = aTrimmedName ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// check for empty names
if ( ! pName [ 0 ] )
return - 1 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// make sure that two clients doesn't have the same name
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
if ( i ! = ClientID & & m_aClients [ i ] . m_State > = CClient : : STATE_READY )
{
if ( str_comp ( pName , m_aClients [ i ] . m_aName ) = = 0 )
return - 1 ;
}
// set the client name
str_copy ( m_aClients [ ClientID ] . m_aName , pName , MAX_NAME_LENGTH ) ;
return 0 ;
}
void CServer : : SetClientName ( int ClientID , const char * pName )
{
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS | | m_aClients [ ClientID ] . m_State < CClient : : STATE_READY )
return ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( ! pName )
return ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
char aNameTry [ MAX_NAME_LENGTH ] ;
str_copy ( aNameTry , pName , MAX_NAME_LENGTH ) ;
if ( TrySetClientName ( ClientID , aNameTry ) )
{
// auto rename
for ( int i = 1 ; ; i + + )
{
str_format ( aNameTry , MAX_NAME_LENGTH , " (%d)%s " , i , pName ) ;
if ( TrySetClientName ( ClientID , aNameTry ) = = 0 )
break ;
}
}
}
void CServer : : SetClientScore ( int ClientID , int Score )
{
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS | | m_aClients [ ClientID ] . m_State < CClient : : STATE_READY )
return ;
m_aClients [ ClientID ] . m_Score = Score ;
}
void CServer : : SetBrowseInfo ( const char * pGameType , int Progression )
{
str_copy ( m_aBrowseinfoGametype , pGameType , sizeof ( m_aBrowseinfoGametype ) ) ;
m_BrowseinfoProgression = Progression ;
if ( m_BrowseinfoProgression > 100 )
m_BrowseinfoProgression = 100 ;
if ( m_BrowseinfoProgression < - 1 )
m_BrowseinfoProgression = - 1 ;
}
void CServer : : Kick ( int ClientID , const char * pReason )
{
2010-09-12 10:07:10 +00:00
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS | | m_aClients [ ClientID ] . m_State = = CClient : : STATE_EMPTY )
2010-09-12 11:52:25 +00:00
{
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " invalid client id to kick " ) ;
2010-05-29 07:25:38 +00:00
return ;
2010-09-12 11:52:25 +00:00
}
else if ( m_RconClientId = = ClientID )
{
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " you can't kick yourself " ) ;
return ;
2010-09-12 10:07:10 +00:00
}
2010-05-29 07:25:38 +00:00
2010-09-12 10:07:10 +00:00
m_NetServer . Drop ( ClientID , pReason ) ;
2010-05-29 07:25:38 +00:00
}
/*int CServer::Tick()
{
return m_CurrentGameTick ;
} */
int64 CServer : : TickStartTime ( int Tick )
{
return m_GameStartTime + ( time_freq ( ) * Tick ) / SERVER_TICK_SPEED ;
}
/*int CServer::TickSpeed()
{
return SERVER_TICK_SPEED ;
} */
int CServer : : Init ( )
{
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
m_aClients [ i ] . m_State = CClient : : STATE_EMPTY ;
m_aClients [ i ] . m_aName [ 0 ] = 0 ;
m_aClients [ i ] . m_aClan [ 0 ] = 0 ;
m_aClients [ i ] . m_Snapshots . Init ( ) ;
}
m_CurrentGameTick = 0 ;
return 0 ;
}
2010-06-02 02:42:17 +00:00
bool CServer : : IsAuthed ( int ClientID )
{
2010-07-30 12:50:09 +00:00
return m_aClients [ ClientID ] . m_Authed ; //TODO: return int
2010-06-02 02:42:17 +00:00
}
2010-05-29 07:25:38 +00:00
int CServer : : GetClientInfo ( int ClientID , CClientInfo * pInfo )
{
dbg_assert ( ClientID > = 0 & & ClientID < MAX_CLIENTS , " client_id is not valid " ) ;
dbg_assert ( pInfo ! = 0 , " info can not be null " ) ;
if ( m_aClients [ ClientID ] . m_State = = CClient : : STATE_INGAME )
{
pInfo - > m_pName = m_aClients [ ClientID ] . m_aName ;
pInfo - > m_Latency = m_aClients [ ClientID ] . m_Latency ;
return 1 ;
}
return 0 ;
}
void CServer : : GetClientIP ( int ClientID , char * pIPString , int Size )
{
if ( ClientID > = 0 & & ClientID < MAX_CLIENTS & & m_aClients [ ClientID ] . m_State = = CClient : : STATE_INGAME )
{
NETADDR Addr = m_NetServer . ClientAddr ( ClientID ) ;
str_format ( pIPString , Size , " %d.%d.%d.%d " , Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] ) ;
}
}
2010-07-29 05:21:18 +00:00
void CServer : : SetClientAuthed ( int ClientID , int Level ) {
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS | | m_aClients [ ClientID ] . m_State = = CClient : : STATE_READY )
{
return ;
}
m_aClients [ ClientID ] . m_Authed = Level ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
int * CServer : : LatestInput ( int ClientId , int * size )
{
if ( ClientId < 0 | | ClientId > = MAX_CLIENTS | | m_aClients [ ClientId ] . m_State < CServer : : CClient : : STATE_READY )
return 0 ;
return m_aClients [ ClientId ] . m_LatestInput . m_aData ;
}
const char * CServer : : ClientName ( int ClientId )
{
if ( ClientId < 0 | | ClientId > = MAX_CLIENTS | | m_aClients [ ClientId ] . m_State < CServer : : CClient : : STATE_READY )
return " (invalid client) " ;
return m_aClients [ ClientId ] . m_aName ;
2010-08-22 16:06:20 +00:00
}
2010-05-29 07:25:38 +00:00
bool CServer : : ClientIngame ( int ClientID )
{
return ClientID > = 0 & & ClientID < MAX_CLIENTS & & m_aClients [ ClientID ] . m_State = = CServer : : CClient : : STATE_INGAME ;
}
int CServer : : SendMsg ( CMsgPacker * pMsg , int Flags , int ClientId )
{
return SendMsgEx ( pMsg , Flags , ClientId , false ) ;
}
int CServer : : SendMsgEx ( CMsgPacker * pMsg , int Flags , int ClientID , bool System )
{
CNetChunk Packet ;
if ( ! pMsg )
return - 1 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
mem_zero ( & Packet , sizeof ( CNetChunk ) ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
Packet . m_ClientID = ClientID ;
Packet . m_pData = pMsg - > Data ( ) ;
Packet . m_DataSize = pMsg - > Size ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// HACK: modify the message id in the packet and store the system flag
* ( ( unsigned char * ) Packet . m_pData ) < < = 1 ;
if ( System )
* ( ( unsigned char * ) Packet . m_pData ) | = 1 ;
if ( Flags & MSGFLAG_VITAL )
Packet . m_Flags | = NETSENDFLAG_VITAL ;
if ( Flags & MSGFLAG_FLUSH )
Packet . m_Flags | = NETSENDFLAG_FLUSH ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// write message to demo recorder
if ( ! ( Flags & MSGFLAG_NORECORD ) )
m_DemoRecorder . RecordMessage ( pMsg - > Data ( ) , pMsg - > Size ( ) ) ;
if ( ! ( Flags & MSGFLAG_NOSEND ) )
{
if ( ClientID = = - 1 )
{
// broadcast
int i ;
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
if ( m_aClients [ i ] . m_State = = CClient : : STATE_INGAME )
{
Packet . m_ClientID = i ;
m_NetServer . Send ( & Packet ) ;
}
}
else
m_NetServer . Send ( & Packet ) ;
}
return 0 ;
}
void CServer : : DoSnapshot ( )
{
GameServer ( ) - > OnPreSnap ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// create snapshot for demo recording
if ( m_DemoRecorder . IsRecording ( ) )
{
char aData [ CSnapshot : : MAX_SIZE ] ;
int SnapshotSize ;
// build snap and possibly add some messages
m_SnapshotBuilder . Init ( ) ;
GameServer ( ) - > OnSnap ( - 1 ) ;
SnapshotSize = m_SnapshotBuilder . Finish ( aData ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// write snapshot
m_DemoRecorder . RecordSnapshot ( Tick ( ) , aData , SnapshotSize ) ;
}
// create snapshots for all clients
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
// client must be ingame to recive snapshots
if ( m_aClients [ i ] . m_State ! = CClient : : STATE_INGAME )
continue ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// this client is trying to recover, don't spam snapshots
if ( m_aClients [ i ] . m_SnapRate = = CClient : : SNAPRATE_RECOVER & & ( Tick ( ) % 50 ) ! = 0 )
continue ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// this client is trying to recover, don't spam snapshots
if ( m_aClients [ i ] . m_SnapRate = = CClient : : SNAPRATE_INIT & & ( Tick ( ) % 10 ) ! = 0 )
continue ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
{
char aData [ CSnapshot : : MAX_SIZE ] ;
2010-06-09 16:24:38 +00:00
CSnapshot * pData = ( CSnapshot * ) aData ; // Fix compiler warning for strict-aliasing
2010-05-29 07:25:38 +00:00
char aDeltaData [ CSnapshot : : MAX_SIZE ] ;
char aCompData [ CSnapshot : : MAX_SIZE ] ;
int SnapshotSize ;
int Crc ;
static CSnapshot EmptySnap ;
CSnapshot * pDeltashot = & EmptySnap ;
int DeltashotSize ;
int DeltaTick = - 1 ;
int DeltaSize ;
m_SnapshotBuilder . Init ( ) ;
GameServer ( ) - > OnSnap ( i ) ;
// finish snapshot
2010-06-09 16:24:38 +00:00
SnapshotSize = m_SnapshotBuilder . Finish ( pData ) ;
Crc = pData - > Crc ( ) ;
2010-05-29 07:25:38 +00:00
// remove old snapshos
// keep 3 seconds worth of snapshots
m_aClients [ i ] . m_Snapshots . PurgeUntil ( m_CurrentGameTick - SERVER_TICK_SPEED * 3 ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// save it the snapshot
2010-06-09 16:24:38 +00:00
m_aClients [ i ] . m_Snapshots . Add ( m_CurrentGameTick , time_get ( ) , SnapshotSize , pData , 0 ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// find snapshot that we can preform delta against
EmptySnap . Clear ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
{
DeltashotSize = m_aClients [ i ] . m_Snapshots . Get ( m_aClients [ i ] . m_LastAckedSnapshot , 0 , & pDeltashot , 0 ) ;
if ( DeltashotSize > = 0 )
DeltaTick = m_aClients [ i ] . m_LastAckedSnapshot ;
else
{
// no acked package found, force client to recover rate
if ( m_aClients [ i ] . m_SnapRate = = CClient : : SNAPRATE_FULL )
m_aClients [ i ] . m_SnapRate = CClient : : SNAPRATE_RECOVER ;
}
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// create delta
2010-06-09 16:24:38 +00:00
DeltaSize = m_SnapshotDelta . CreateDelta ( pDeltashot , pData , aDeltaData ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( DeltaSize )
{
// compress it
int SnapshotSize ;
const int MaxSize = MAX_SNAPSHOT_PACKSIZE ;
int NumPackets ;
SnapshotSize = CVariableInt : : Compress ( aDeltaData , DeltaSize , aCompData ) ;
NumPackets = ( SnapshotSize + MaxSize - 1 ) / MaxSize ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
for ( int n = 0 , Left = SnapshotSize ; Left ; n + + )
{
int Chunk = Left < MaxSize ? Left : MaxSize ;
Left - = Chunk ;
if ( NumPackets = = 1 )
{
CMsgPacker Msg ( NETMSG_SNAPSINGLE ) ;
Msg . AddInt ( m_CurrentGameTick ) ;
Msg . AddInt ( m_CurrentGameTick - DeltaTick ) ;
Msg . AddInt ( Crc ) ;
Msg . AddInt ( Chunk ) ;
Msg . AddRaw ( & aCompData [ n * MaxSize ] , Chunk ) ;
SendMsgEx ( & Msg , MSGFLAG_FLUSH , i , true ) ;
}
else
{
CMsgPacker Msg ( NETMSG_SNAP ) ;
Msg . AddInt ( m_CurrentGameTick ) ;
Msg . AddInt ( m_CurrentGameTick - DeltaTick ) ;
Msg . AddInt ( NumPackets ) ;
2010-08-22 16:06:20 +00:00
Msg . AddInt ( n ) ;
2010-05-29 07:25:38 +00:00
Msg . AddInt ( Crc ) ;
Msg . AddInt ( Chunk ) ;
Msg . AddRaw ( & aCompData [ n * MaxSize ] , Chunk ) ;
SendMsgEx ( & Msg , MSGFLAG_FLUSH , i , true ) ;
}
}
}
else
{
CMsgPacker Msg ( NETMSG_SNAPEMPTY ) ;
Msg . AddInt ( m_CurrentGameTick ) ;
Msg . AddInt ( m_CurrentGameTick - DeltaTick ) ;
SendMsgEx ( & Msg , MSGFLAG_FLUSH , i , true ) ;
}
}
}
GameServer ( ) - > OnPostSnap ( ) ;
}
int CServer : : NewClientCallback ( int ClientId , void * pUser )
{
CServer * pThis = ( CServer * ) pUser ;
pThis - > m_aClients [ ClientId ] . m_State = CClient : : STATE_AUTH ;
pThis - > m_aClients [ ClientId ] . m_aName [ 0 ] = 0 ;
pThis - > m_aClients [ ClientId ] . m_aClan [ 0 ] = 0 ;
pThis - > m_aClients [ ClientId ] . m_Authed = 0 ;
2010-08-22 16:06:20 +00:00
pThis - > m_aClients [ ClientId ] . m_PwTries = 0 ; // init pw tries
memset ( & pThis - > m_aClients [ ClientId ] . m_Addr , 0 , sizeof ( NETADDR ) ) ; // init that too
2010-07-30 12:50:09 +00:00
pThis - > m_aClients [ ClientId ] . m_CmdTriesTimer = 0 ;
2010-08-22 16:06:20 +00:00
pThis - > m_aClients [ ClientId ] . m_CmdTries = 0 ; //Floff init cmd tries
pThis - > m_aClients [ ClientId ] . m_Resistent = 0 ;
2010-05-29 07:25:38 +00:00
pThis - > m_aClients [ ClientId ] . Reset ( ) ;
return 0 ;
}
2010-08-17 22:06:00 +00:00
int CServer : : DelClientCallback ( int ClientId , const char * pReason , void * pUser )
2010-05-29 07:25:38 +00:00
{
CServer * pThis = ( CServer * ) pUser ;
2010-08-22 16:06:20 +00:00
2010-08-17 22:06:00 +00:00
NETADDR Addr = pThis - > m_NetServer . ClientAddr ( ClientId ) ;
char aBuf [ 256 ] ;
2010-09-17 14:40:11 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " client dropped. ClientId=%d ip=%d.%d.%d.%d reason='%s' " ,
2010-08-17 22:06:00 +00:00
ClientId ,
Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] ,
pReason
) ;
pThis - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
// notify the mod about the drop
if ( pThis - > m_aClients [ ClientId ] . m_State > = CClient : : STATE_READY )
pThis - > GameServer ( ) - > OnClientDrop ( ClientId ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
pThis - > m_aClients [ ClientId ] . m_State = CClient : : STATE_EMPTY ;
pThis - > m_aClients [ ClientId ] . m_aName [ 0 ] = 0 ;
pThis - > m_aClients [ ClientId ] . m_aClan [ 0 ] = 0 ;
pThis - > m_aClients [ ClientId ] . m_Authed = 0 ;
2010-08-22 16:06:20 +00:00
pThis - > m_aClients [ ClientId ] . m_PwTries = 0 ; // init pw tries
memset ( & pThis - > m_aClients [ ClientId ] . m_Addr , 0 , sizeof ( NETADDR ) ) ; // init that too
pThis - > m_aClients [ ClientId ] . m_CmdTriesTimer = 0 ;
pThis - > m_aClients [ ClientId ] . m_CmdTries = 0 ; //Floff init cmd tries
pThis - > m_aClients [ ClientId ] . m_Resistent = 0 ;
2010-05-29 07:25:38 +00:00
pThis - > m_aClients [ ClientId ] . m_Snapshots . PurgeAll ( ) ;
return 0 ;
}
void CServer : : SendMap ( int ClientId )
{
2010-06-05 08:44:50 +00:00
//get the name of the map without his path
char * pMapShortName = & g_Config . m_SvMap [ 0 ] ;
2010-06-09 16:24:38 +00:00
for ( int i = 0 ; i < str_length ( g_Config . m_SvMap ) - 1 ; i + + )
2010-06-05 08:44:50 +00:00
{
2010-06-07 01:38:38 +00:00
if ( g_Config . m_SvMap [ i ] = = ' / ' | | g_Config . m_SvMap [ i ] = = ' \\ ' )
2010-06-05 08:44:50 +00:00
pMapShortName = & g_Config . m_SvMap [ i + 1 ] ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
CMsgPacker Msg ( NETMSG_MAP_CHANGE ) ;
2010-06-05 08:44:50 +00:00
Msg . AddString ( pMapShortName , 0 ) ;
2010-05-29 07:25:38 +00:00
Msg . AddInt ( m_CurrentMapCrc ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL | MSGFLAG_FLUSH , ClientId , true ) ;
}
void CServer : : SendRconLine ( int ClientId , const char * pLine )
{
CMsgPacker Msg ( NETMSG_RCON_LINE ) ;
Msg . AddString ( pLine , 512 ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL , ClientId , true ) ;
}
void CServer : : SendRconLineAuthed ( const char * pLine , void * pUser )
{
CServer * pThis = ( CServer * ) pUser ;
static volatile int ReentryGuard = 0 ;
int i ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( ReentryGuard ) return ;
ReentryGuard + + ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( pThis - > m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY & & pThis - > m_aClients [ i ] . m_Authed )
pThis - > SendRconLine ( i , pLine ) ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
ReentryGuard - - ;
}
void CServer : : ProcessClientPacket ( CNetChunk * pPacket )
{
int ClientId = pPacket - > m_ClientID ;
NETADDR Addr ;
CUnpacker Unpacker ;
Unpacker . Reset ( pPacket - > m_pData , pPacket - > m_DataSize ) ;
// unpack msgid and system flag
int Msg = Unpacker . GetInt ( ) ;
int Sys = Msg & 1 ;
Msg > > = 1 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( Unpacker . Error ( ) )
return ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( m_aClients [ ClientId ] . m_State = = CClient : : STATE_AUTH )
{
if ( Sys & & Msg = = NETMSG_INFO )
{
char aVersion [ 64 ] ;
const char * pPassword ;
2010-08-12 13:22:07 +00:00
str_copy ( aVersion , Unpacker . GetString ( CUnpacker : : SANITIZE_CC ) , 64 ) ;
2010-05-29 07:25:38 +00:00
if ( str_comp ( aVersion , GameServer ( ) - > NetVersion ( ) ) ! = 0 )
{
// OH FUCK! wrong version, drop him
char aReason [ 256 ] ;
str_format ( aReason , sizeof ( aReason ) , " wrong version. server is running '%s' and client '%s'. " , GameServer ( ) - > NetVersion ( ) , aVersion ) ;
m_NetServer . Drop ( ClientId , aReason ) ;
return ;
}
2010-08-22 16:06:20 +00:00
2010-08-12 13:22:07 +00:00
str_copy ( m_aClients [ ClientId ] . m_aName , Unpacker . GetString ( CUnpacker : : SANITIZE_CC | CUnpacker : : SKIP_START_WHITESPACES ) , MAX_NAME_LENGTH ) ;
str_copy ( m_aClients [ ClientId ] . m_aClan , Unpacker . GetString ( CUnpacker : : SANITIZE_CC | CUnpacker : : SKIP_START_WHITESPACES ) , MAX_CLANNAME_LENGTH ) ;
pPassword = Unpacker . GetString ( CUnpacker : : SANITIZE_CC ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( g_Config . m_Password [ 0 ] ! = 0 & & str_comp ( g_Config . m_Password , pPassword ) ! = 0 )
{
// wrong password
m_NetServer . Drop ( ClientId , " wrong password " ) ;
return ;
}
2010-08-22 16:06:20 +00:00
2010-07-29 05:21:18 +00:00
// reserved slot
2010-08-22 16:06:20 +00:00
if ( ClientId > = ( g_Config . m_SvMaxClients - g_Config . m_SvReservedSlots ) & & g_Config . m_SvReservedSlotsPass [ 0 ] ! = 0 & & strcmp ( g_Config . m_SvReservedSlotsPass , pPassword ) ! = 0 )
{
m_NetServer . Drop ( ClientId , " Dropped due reserved slot " ) ;
return ;
2010-07-29 05:21:18 +00:00
}
2010-08-22 16:06:20 +00:00
2010-07-29 10:09:25 +00:00
//Start of 2cpip LemonFace
int i /*, ipcnt = 0*/ ; // ip count
Addr = m_NetServer . ClientAddr ( ClientId ) ;
2010-08-22 16:06:20 +00:00
m_aClients [ ClientId ] . m_Addr = Addr ; // store the address info
2010-07-29 10:09:25 +00:00
/*for(i=0; i<MAX_CLIENTS; i++)
2010-08-22 16:06:20 +00:00
{
if ( m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY ) // if not an empty slot
{
if ( m_aClients [ i ] . m_Addr . ip [ 0 ] = = Addr . ip [ 0 ] & & // check each ip byte
m_aClients [ i ] . m_Addr . ip [ 1 ] = = Addr . ip [ 1 ] & &
m_aClients [ i ] . m_Addr . ip [ 2 ] = = Addr . ip [ 2 ] & &
m_aClients [ i ] . m_Addr . ip [ 3 ] = = Addr . ip [ 3 ] )
{
2010-07-29 10:09:25 +00:00
if ( m_aClients [ i ] . m_Authed > 0 ) // authed players can have clones
2010-08-22 16:06:20 +00:00
{
ipcnt = 0 ;
break ;
}
ipcnt + + ; // ++
}
}
}
2010-07-29 10:09:25 +00:00
if ( ipcnt > g_Config . m_SvMaxConnections ) // if already n connections exist, drop him
2010-08-22 16:06:20 +00:00
{
2010-07-29 10:09:25 +00:00
dbg_msg ( " server " , " Player dropped, too many connections. cid=%x ip=%d.%d.%d.%d " ,
ClientId ,
Addr . ip [ 0 ] ,
Addr . ip [ 1 ] ,
Addr . ip [ 2 ] ,
Addr . ip [ 3 ]
) ;
char buf [ 100 ] ;
str_format ( buf , sizeof ( buf ) , " Connection count(%d) per IP Limit Exceeded, The Limit is %d " , ipcnt , g_Config . m_SvMaxClientsPerIP ) ;
m_NetServer . Drop ( ClientId , buf ) ;
2010-08-22 16:06:20 +00:00
return ;
2010-07-29 10:09:25 +00:00
} */
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_aClients [ ClientId ] . m_State = CClient : : STATE_CONNECTING ;
SendMap ( ClientId ) ;
}
}
2010-09-06 02:59:02 +00:00
else
{
if ( m_aClients [ ClientId ] . m_Authed = = 0 & & Msg ! = NETMSG_INPUT & & Msg ! = NETMSG_REQUEST_MAP_DATA )
{
if ( time_get ( ) > m_aClients [ ClientId ] . m_CmdTriesTimer + time_freq ( ) )
2010-07-29 19:55:33 +00:00
{
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_CmdTries = 0 ;
m_aClients [ ClientId ] . m_CmdTriesTimer = time_get ( ) ;
}
m_aClients [ ClientId ] . m_CmdTries + + ;
//dbg_msg("server","client_counter: %d", clients[cid].command_tries);
2010-07-29 19:55:33 +00:00
2010-09-06 02:59:02 +00:00
if ( m_aClients [ ClientId ] . m_CmdTries > g_Config . m_SvNetmsgLimit & & g_Config . m_SvNetmsgLimit ! = 0 )
{
dbg_msg ( " server " , " client sending too many messages to server (DDoS?), banned. cid=%x ip=%d.%d.%d.%d " ,
ClientId ,
m_aClients [ ClientId ] . m_Addr . ip [ 0 ] , m_aClients [ ClientId ] . m_Addr . ip [ 1 ] , m_aClients [ ClientId ] . m_Addr . ip [ 2 ] , m_aClients [ ClientId ] . m_Addr . ip [ 3 ]
) ;
2010-07-29 19:55:33 +00:00
2010-09-06 02:59:02 +00:00
BanAdd ( m_aClients [ ClientId ] . m_Addr , g_Config . m_SvNetmsgBanTime , " exceeding netmsg_limit, Bye " ) ; // bye
return ;
2010-07-29 19:55:33 +00:00
}
}
2010-09-06 02:59:02 +00:00
}
if ( Sys )
{
if ( Msg ! = NETMSG_INPUT & & Msg ! = NETMSG_REQUEST_MAP_DATA )
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_CmdTries + + ;
if ( time_get ( ) < m_aClients [ ClientId ] . m_CmdTriesTimer + time_freq ( ) /* * 1*/ )
2010-07-29 19:55:33 +00:00
{
2010-09-06 02:59:02 +00:00
if ( m_aClients [ ClientId ] . m_CmdTries > g_Config . m_SvNetmsgLimit & & g_Config . m_SvNetmsgLimit ! = 0 )
2010-07-29 19:55:33 +00:00
{
2010-09-06 02:59:02 +00:00
dbg_msg ( " server " , " client trying to flood the server (%d tries), ban. cid=%x ip=%d.%d.%d.%d " , m_aClients [ ClientId ] . m_CmdTries ,
ClientId ,
m_aClients [ ClientId ] . m_Addr . ip [ 0 ] , m_aClients [ ClientId ] . m_Addr . ip [ 1 ] , m_aClients [ ClientId ] . m_Addr . ip [ 2 ] , m_aClients [ ClientId ] . m_Addr . ip [ 3 ]
) ;
BanAdd ( m_aClients [ ClientId ] . m_Addr , g_Config . m_SvNetmsgBanTime , " exceeding netmsg_limit, Bye " ) ; // bye
return ;
2010-07-29 19:55:33 +00:00
}
}
2010-09-06 02:59:02 +00:00
else
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_CmdTries = 0 ;
}
m_aClients [ ClientId ] . m_CmdTriesTimer = time_get ( ) ;
}
// system message
if ( Msg = = NETMSG_REQUEST_MAP_DATA )
{
int Chunk = Unpacker . GetInt ( ) ;
int ChunkSize = 1024 - 128 ;
int Offset = Chunk * ChunkSize ;
int Last = 0 ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
// drop faulty map data requests
if ( Chunk < 0 | | Offset > m_CurrentMapSize )
return ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
if ( Offset + ChunkSize > = m_CurrentMapSize )
{
ChunkSize = m_CurrentMapSize - Offset ;
if ( ChunkSize < 0 )
ChunkSize = 0 ;
Last = 1 ;
}
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
CMsgPacker Msg ( NETMSG_MAP_DATA ) ;
Msg . AddInt ( Last ) ;
Msg . AddInt ( m_CurrentMapSize ) ;
Msg . AddInt ( ChunkSize ) ;
Msg . AddRaw ( & m_pCurrentMapData [ Offset ] , ChunkSize ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL | MSGFLAG_FLUSH , ClientId , true ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
if ( g_Config . m_Debug )
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " sending chunk %d with size %d " , Chunk , ChunkSize ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
2010-09-06 02:59:02 +00:00
}
else if ( Msg = = NETMSG_READY )
{
if ( m_aClients [ ClientId ] . m_State = = CClient : : STATE_CONNECTING )
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
//Addr = m_NetServer.ClientAddr(ClientId);
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " player is ready. ClientId=%x ip=%d.%d.%d.%d " ,
ClientId ,
m_aClients [ ClientId ] . m_Addr . ip [ 0 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 1 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 2 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 3 ] ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ;
m_aClients [ ClientId ] . m_State = CClient : : STATE_READY ;
GameServer ( ) - > OnClientConnected ( ClientId ) ;
GameServer ( ) - > OnSetAuthed ( ClientId , m_aClients [ ClientId ] . m_Authed ) ;
GameServer ( ) - > OnSetResistent ( ClientId , m_aClients [ ClientId ] . m_Resistent ) ;
2010-05-29 07:25:38 +00:00
}
2010-09-06 02:59:02 +00:00
}
else if ( Msg = = NETMSG_ENTERGAME )
{
if ( m_aClients [ ClientId ] . m_State = = CClient : : STATE_READY )
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
//Addr = m_NetServer.ClientAddr(ClientId);
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " player has entered the game. ClientId=%x ip=%d.%d.%d.%d " ,
ClientId ,
m_aClients [ ClientId ] . m_Addr . ip [ 0 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 1 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 2 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 3 ] ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
m_aClients [ ClientId ] . m_State = CClient : : STATE_INGAME ;
GameServer ( ) - > OnClientEnter ( ClientId ) ;
}
}
else if ( Msg = = NETMSG_INPUT )
{
CClient : : CInput * pInput ;
int64 TagTime ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_LastAckedSnapshot = Unpacker . GetInt ( ) ;
int IntendedTick = Unpacker . GetInt ( ) ;
int Size = Unpacker . GetInt ( ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
// check for errors
if ( Unpacker . Error ( ) | | Size / 4 > MAX_INPUT_SIZE )
return ;
2010-05-29 07:25:38 +00:00
2010-09-06 02:59:02 +00:00
if ( m_aClients [ ClientId ] . m_LastAckedSnapshot > 0 )
m_aClients [ ClientId ] . m_SnapRate = CClient : : SNAPRATE_FULL ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
if ( m_aClients [ ClientId ] . m_Snapshots . Get ( m_aClients [ ClientId ] . m_LastAckedSnapshot , & TagTime , 0 , 0 ) > = 0 )
m_aClients [ ClientId ] . m_Latency = ( int ) ( ( ( time_get ( ) - TagTime ) * 1000 ) / time_freq ( ) ) ;
2010-05-29 07:25:38 +00:00
2010-09-06 02:59:02 +00:00
// add message to report the input timing
// skip packets that are old
if ( IntendedTick > m_aClients [ ClientId ] . m_LastInputTick )
{
int TimeLeft = ( ( TickStartTime ( IntendedTick ) - time_get ( ) ) * 1000 ) / time_freq ( ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
CMsgPacker Msg ( NETMSG_INPUTTIMING ) ;
Msg . AddInt ( IntendedTick ) ;
Msg . AddInt ( TimeLeft ) ;
SendMsgEx ( & Msg , 0 , ClientId , true ) ;
}
2010-05-29 07:25:38 +00:00
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_LastInputTick = IntendedTick ;
2010-05-29 07:25:38 +00:00
2010-09-06 02:59:02 +00:00
pInput = & m_aClients [ ClientId ] . m_aInputs [ m_aClients [ ClientId ] . m_CurrentInput ] ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
if ( IntendedTick < = Tick ( ) )
IntendedTick = Tick ( ) + 1 ;
2010-05-29 07:25:38 +00:00
2010-09-06 02:59:02 +00:00
pInput - > m_GameTick = IntendedTick ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
for ( int i = 0 ; i < Size / 4 ; i + + )
pInput - > m_aData [ i ] = Unpacker . GetInt ( ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
mem_copy ( m_aClients [ ClientId ] . m_LatestInput . m_aData , pInput - > m_aData , MAX_INPUT_SIZE * sizeof ( int ) ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_CurrentInput + + ;
m_aClients [ ClientId ] . m_CurrentInput % = 200 ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
// call the mod with the fresh input data
if ( m_aClients [ ClientId ] . m_State = = CClient : : STATE_INGAME )
GameServer ( ) - > OnClientDirectInput ( ClientId , m_aClients [ ClientId ] . m_LatestInput . m_aData ) ;
}
else if ( Msg = = NETMSG_RCON_CMD )
{
const char * pCmd = Unpacker . GetString ( ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
if ( Unpacker . Error ( ) = = 0 /* && m_aClients[ClientId].m_Authed*/ )
{
char aBuf [ 256 ] ;
2010-09-17 14:37:03 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " '%s' ClientId=%d Level=%d Rcon='%s' " , ClientName ( ClientId ) , ClientId , m_aClients [ ClientId ] . m_Authed , pCmd ) ;
2010-09-06 02:59:02 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ;
//Addr = m_NetServer.ClientAddr(ClientId);
if ( m_aClients [ ClientId ] . m_Authed > 0 )
2010-05-29 07:25:38 +00:00
{
2010-09-17 14:42:38 +00:00
/*char aBuf[256];
2010-09-17 14:37:03 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " '%s' ClientId=%d rcon='%s' " , ClientName ( ClientId ) , ClientId , pCmd ) ;
2010-09-17 14:42:38 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ; */
2010-09-12 11:52:25 +00:00
m_RconClientId = ClientId ;
2010-08-25 13:24:31 +00:00
Console ( ) - > ExecuteLine ( pCmd , m_aClients [ ClientId ] . m_Authed , ClientId ) ;
2010-09-12 11:52:25 +00:00
m_RconClientId = - 1 ;
2010-05-29 07:25:38 +00:00
}
2010-09-13 04:49:01 +00:00
else
{
2010-09-06 02:59:02 +00:00
dbg_msg ( " server " , " client tried rcon command without permissions. Cid=%x ip=%d.%d.%d.%d " ,
ClientId ,
m_aClients [ ClientId ] . m_Addr . ip [ 0 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 1 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 2 ] ,
m_aClients [ ClientId ] . m_Addr . ip [ 3 ] ) ;
//BanAdd(m_aClients[ClientId].m_Addr, g_Config.m_SvRconTriesBantime,"Trying Rcon commands withou permission"); // bye
2010-05-29 07:25:38 +00:00
}
2010-09-06 02:59:02 +00:00
2010-05-29 07:25:38 +00:00
}
2010-09-06 02:59:02 +00:00
}
else if ( Msg = = NETMSG_RCON_AUTH )
{
const char * pPw ;
Unpacker . GetString ( ) ; // login name, not used
pPw = Unpacker . GetString ( CUnpacker : : SANITIZE_CC ) ;
2010-08-22 16:06:20 +00:00
2010-09-06 02:59:02 +00:00
if ( Unpacker . Error ( ) = = 0 )
{
if ( pPw [ 0 ] ! = 0 )
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
if ( g_Config . m_SvRconPasswordHelper [ 0 ] = = 0 & &
g_Config . m_SvRconPasswordModer [ 0 ] = = 0 & &
g_Config . m_SvRconPasswordAdmin [ 0 ] = = 0 )
2010-05-29 07:25:38 +00:00
{
2010-09-17 02:05:14 +00:00
SendRconLine ( ClientId , " No rcon password set on server. Set sv_admin_pass/sv_mod_pass/sv_helper_pass to enable the remote console. " ) ;
2010-09-06 02:59:02 +00:00
}
else
{
/*else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0)
{
CMsgPacker Msg ( NETMSG_RCON_AUTH_STATUS ) ;
Msg . AddInt ( 1 ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL , ClientId , true ) ;
m_aClients [ ClientId ] . m_Authed = 1 ;
SendRconLine ( ClientId , " Authentication successful. Remote console access granted. " ) ;
dbg_msg ( " server " , " ClientId=%d authed " , ClientId ) ;
} */
int level = - 1 ;
if ( str_comp ( pPw , g_Config . m_SvRconPasswordHelper ) = = 0 )
2010-07-29 05:21:18 +00:00
{
2010-09-06 02:59:02 +00:00
level = 1 ;
}
else if ( str_comp ( pPw , g_Config . m_SvRconPasswordModer ) = = 0 )
{
level = 2 ;
}
else if ( str_comp ( pPw , g_Config . m_SvRconPasswordAdmin ) = = 0 )
{
level = 3 ;
}
if ( level ! = - 1 )
{
2010-09-17 14:37:03 +00:00
char buf [ 128 ] = " Authentication successful. Remote console access grantedfor ClientId=%d with level=%d " ;
2010-09-06 02:59:02 +00:00
CMsgPacker Msg ( NETMSG_RCON_AUTH_STATUS ) ;
Msg . AddInt ( 1 ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL , ClientId , true ) ;
m_aClients [ ClientId ] . m_Authed = level ;
GameServer ( ) - > OnSetAuthed ( ClientId , m_aClients [ ClientId ] . m_Authed ) ;
str_format ( buf , sizeof ( buf ) , buf , ClientId , level ) ;
SendRconLine ( ClientId , buf ) ;
2010-09-17 14:37:03 +00:00
dbg_msg ( " server " , " '%s' ClientId=%d authed with Level=%d " , ClientName ( ClientId ) , ClientId , level ) ;
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_PwTries = 0 ;
2010-08-22 16:06:20 +00:00
}
else
2010-07-29 05:21:18 +00:00
{
2010-09-06 02:59:02 +00:00
SendRconLine ( ClientId , " Wrong password. " ) ;
if ( + + m_aClients [ ClientId ] . m_PwTries > g_Config . m_SvRconTries )
{ // rcon Kottizen LemonFace
BanAdd ( m_NetServer . ClientAddr ( ClientId ) , g_Config . m_SvRconTriesBantime , " exceeding rcon password tries, Bye " ) ; // bye
2010-09-17 14:37:03 +00:00
dbg_msg ( " server " , " '%s' ClientId=%d banned, wrong rcon pw " , ClientName ( ClientId ) , ClientId ) ;
2010-07-29 09:15:55 +00:00
}
2010-07-29 05:21:18 +00:00
}
2010-05-29 07:25:38 +00:00
}
}
2010-09-06 02:59:02 +00:00
/*else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0)
{
CMsgPacker Msg ( NETMSG_RCON_AUTH_STATUS ) ;
Msg . AddInt ( 1 ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL , ClientId , true ) ;
2010-05-29 07:25:38 +00:00
2010-09-06 02:59:02 +00:00
m_aClients [ ClientId ] . m_Authed = 1 ;
SendRconLine ( ClientId , " Authentication successful. Remote console access granted. " ) ;
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " ClientId=%d authed " , ClientId ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
} */
else
2010-05-29 07:25:38 +00:00
{
2010-09-06 02:59:02 +00:00
SendRconLine ( ClientId , " Wrong password. " ) ;
dbg_msg ( " server " , " Client tried to authenticate with empty password. cid=%x ip=%d.%d.%d.%d " ,
ClientId ,
m_aClients [ ClientId ] . m_Addr . ip [ 0 ] , m_aClients [ ClientId ] . m_Addr . ip [ 1 ] , m_aClients [ ClientId ] . m_Addr . ip [ 2 ] , m_aClients [ ClientId ] . m_Addr . ip [ 3 ]
) ;
2010-05-29 07:25:38 +00:00
}
}
}
2010-09-06 02:59:02 +00:00
else if ( Msg = = NETMSG_PING )
{
CMsgPacker Msg ( NETMSG_PING_REPLY ) ;
SendMsgEx ( & Msg , 0 , ClientId , true ) ;
}
2010-05-29 07:25:38 +00:00
else
{
2010-09-06 02:59:02 +00:00
char aHex [ ] = " 0123456789ABCDEF " ;
char aBuf [ 512 ] ;
for ( int b = 0 ; b < pPacket - > m_DataSize & & b < 32 ; b + + )
{
aBuf [ b * 3 ] = aHex [ ( ( const unsigned char * ) pPacket - > m_pData ) [ b ] > > 4 ] ;
aBuf [ b * 3 + 1 ] = aHex [ ( ( const unsigned char * ) pPacket - > m_pData ) [ b ] & 0xf ] ;
aBuf [ b * 3 + 2 ] = ' ' ;
aBuf [ b * 3 + 3 ] = 0 ;
}
char aBufMsg [ 256 ] ;
2010-09-17 14:37:03 +00:00
str_format ( aBufMsg , sizeof ( aBufMsg ) , " strange message from '%s' ClientId=%d msg=%d data_size=%d " , ClientName ( ClientId ) , ClientId , Msg , pPacket - > m_DataSize ) ;
2010-09-06 02:59:02 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBufMsg ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
2010-09-06 02:59:02 +00:00
}
else
{
// game message
if ( m_aClients [ ClientId ] . m_State > = CClient : : STATE_READY )
GameServer ( ) - > OnMessage ( Msg , & Unpacker , ClientId ) ;
}
2010-05-29 07:25:38 +00:00
}
2010-07-30 12:50:09 +00:00
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
void CServer : : SendServerInfo ( NETADDR * pAddr , int Token )
{
CNetChunk Packet ;
CPacker p ;
char aBuf [ 128 ] ;
// count the players
int PlayerCount = 0 ;
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY )
PlayerCount + + ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
p . Reset ( ) ;
if ( Token > = 0 )
{
// new token based format
p . AddRaw ( SERVERBROWSE_INFO , sizeof ( SERVERBROWSE_INFO ) ) ;
str_format ( aBuf , sizeof ( aBuf ) , " %d " , Token ) ;
p . AddString ( aBuf , 6 ) ;
}
else
{
// old format
p . AddRaw ( SERVERBROWSE_OLD_INFO , sizeof ( SERVERBROWSE_OLD_INFO ) ) ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
p . AddString ( GameServer ( ) - > Version ( ) , 32 ) ;
p . AddString ( g_Config . m_SvName , 64 ) ;
p . AddString ( g_Config . m_SvMap , 32 ) ;
// gametype
p . AddString ( m_aBrowseinfoGametype , 16 ) ;
// flags
int i = 0 ;
if ( g_Config . m_Password [ 0 ] ) // password set
i | = SERVER_FLAG_PASSWORD ;
str_format ( aBuf , sizeof ( aBuf ) , " %d " , i ) ;
p . AddString ( aBuf , 2 ) ;
// progression
str_format ( aBuf , sizeof ( aBuf ) , " %d " , m_BrowseinfoProgression ) ;
p . AddString ( aBuf , 4 ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %d " , PlayerCount ) ; p . AddString ( aBuf , 3 ) ; // num players
str_format ( aBuf , sizeof ( aBuf ) , " %d " , m_NetServer . MaxClients ( ) ) ; p . AddString ( aBuf , 3 ) ; // max players
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY )
{
p . AddString ( m_aClients [ i ] . m_aName , 48 ) ; // player name
str_format ( aBuf , sizeof ( aBuf ) , " %d " , m_aClients [ i ] . m_Score ) ; p . AddString ( aBuf , 6 ) ; // player score
}
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
Packet . m_ClientID = - 1 ;
Packet . m_Address = * pAddr ;
Packet . m_Flags = NETSENDFLAG_CONNLESS ;
Packet . m_DataSize = p . Size ( ) ;
Packet . m_pData = p . Data ( ) ;
m_NetServer . Send ( & Packet ) ;
}
void CServer : : UpdateServerInfo ( )
{
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY )
{
NETADDR Addr = m_NetServer . ClientAddr ( i ) ;
SendServerInfo ( & Addr , - 1 ) ; // SERVERBROWSE_OLD_INFO
}
}
}
2010-07-29 19:55:33 +00:00
int CServer : : BanAdd ( NETADDR Addr , int Seconds , const char * Reason )
2010-05-29 07:25:38 +00:00
{
2010-08-22 16:06:20 +00:00
return m_NetServer . BanAdd ( Addr , Seconds , Reason ) ;
2010-05-29 07:25:38 +00:00
}
int CServer : : BanRemove ( NETADDR Addr )
{
return m_NetServer . BanRemove ( Addr ) ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
void CServer : : PumpNetwork ( )
{
CNetChunk Packet ;
m_NetServer . Update ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// process packets
while ( m_NetServer . Recv ( & Packet ) )
{
if ( Packet . m_ClientID = = - 1 )
{
// stateless
if ( ! m_Register . RegisterProcessPacket ( & Packet ) )
{
if ( Packet . m_DataSize = = sizeof ( SERVERBROWSE_GETINFO ) + 1 & &
mem_comp ( Packet . m_pData , SERVERBROWSE_GETINFO , sizeof ( SERVERBROWSE_GETINFO ) ) = = 0 )
{
SendServerInfo ( & Packet . m_Address , ( ( unsigned char * ) Packet . m_pData ) [ sizeof ( SERVERBROWSE_GETINFO ) ] ) ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( Packet . m_DataSize = = sizeof ( SERVERBROWSE_OLD_GETINFO ) & &
mem_comp ( Packet . m_pData , SERVERBROWSE_OLD_GETINFO , sizeof ( SERVERBROWSE_OLD_GETINFO ) ) = = 0 )
{
SendServerInfo ( & Packet . m_Address , - 1 ) ;
}
}
}
else
ProcessClientPacket ( & Packet ) ;
}
}
int CServer : : LoadMap ( const char * pMapName )
{
//DATAFILE *df;
char aBuf [ 512 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " maps/%s.map " , pMapName ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
/*df = datafile_load(buf);
if ( ! df )
return 0 ; */
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( ! m_pMap - > Load ( aBuf ) )
return 0 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// stop recording when we change map
m_DemoRecorder . Stop ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// reinit snapshot ids
m_IDPool . TimeoutIDs ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// get the crc of the map
m_CurrentMapCrc = m_pMap - > Crc ( ) ;
2010-08-17 22:06:00 +00:00
char aBufMsg [ 256 ] ;
str_format ( aBufMsg , sizeof ( aBufMsg ) , " %s crc is %08x " , aBuf , m_CurrentMapCrc ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBufMsg ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
str_copy ( m_aCurrentMap , pMapName , sizeof ( m_aCurrentMap ) ) ;
//map_set(df);
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// load compelate map into memory for download
{
IOHANDLE File = Storage ( ) - > OpenFile ( aBuf , IOFLAG_READ ) ;
m_CurrentMapSize = ( int ) io_length ( File ) ;
if ( m_pCurrentMapData )
mem_free ( m_pCurrentMapData ) ;
m_pCurrentMapData = ( unsigned char * ) mem_alloc ( m_CurrentMapSize , 1 ) ;
io_read ( File , m_pCurrentMapData , m_CurrentMapSize ) ;
io_close ( File ) ;
}
return 1 ;
}
void CServer : : InitEngine ( const char * pAppname )
{
m_Engine . Init ( pAppname ) ;
}
2010-08-17 22:06:00 +00:00
void CServer : : InitRegister ( CNetServer * pNetServer , IEngineMasterServer * pMasterServer , IConsole * pConsole )
2010-05-29 07:25:38 +00:00
{
2010-08-17 22:06:00 +00:00
m_Register . Init ( pNetServer , pMasterServer , pConsole ) ;
2010-05-29 07:25:38 +00:00
}
int CServer : : Run ( )
{
m_pGameServer = Kernel ( ) - > RequestInterface < IGameServer > ( ) ;
m_pMap = Kernel ( ) - > RequestInterface < IEngineMap > ( ) ;
m_pStorage = Kernel ( ) - > RequestInterface < IStorage > ( ) ;
//snap_init_id();
net_init ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
//
Console ( ) - > RegisterPrintCallback ( SendRconLineAuthed , this ) ;
// load map
if ( ! LoadMap ( g_Config . m_SvMap ) )
{
dbg_msg ( " server " , " failed to load map. mapname='%s' " , g_Config . m_SvMap ) ;
return - 1 ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// start server
// TODO: IPv6 support
NETADDR BindAddr ;
if ( g_Config . m_SvBindaddr [ 0 ] & & net_host_lookup ( g_Config . m_SvBindaddr , & BindAddr , NETTYPE_IPV4 ) = = 0 )
{
// sweet!
BindAddr . port = g_Config . m_SvPort ;
}
else
{
mem_zero ( & BindAddr , sizeof ( BindAddr ) ) ;
BindAddr . port = g_Config . m_SvPort ;
}
2010-08-22 16:06:20 +00:00
2010-06-03 12:48:32 +00:00
if ( ! m_NetServer . Open ( BindAddr , g_Config . m_SvMaxClients , g_Config . m_SvMaxClientsPerIP , 0 ) )
2010-05-29 07:25:38 +00:00
{
dbg_msg ( " server " , " couldn't open socket. port might already be in use " ) ;
return - 1 ;
}
2010-07-29 05:21:18 +00:00
m_NetServer . SetCallbacks ( NewClientCallback , DelClientCallback , this , 0 ) ;
2010-08-22 16:06:20 +00:00
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " server name is '%s' " , g_Config . m_SvName ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
GameServer ( ) - > OnInit ( ) ;
2010-08-17 22:06:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " version %s " , GameServer ( ) - > NetVersion ( ) ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
2010-08-07 18:22:25 +00:00
// process pending commands
2010-08-09 14:54:42 +00:00
m_pConsole - > StoreCommands ( false , - 1 ) ;
2010-08-07 18:22:25 +00:00
2010-05-29 07:25:38 +00:00
// start game
{
int64 ReportTime = time_get ( ) ;
int ReportInterval = 3 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_Lastheartbeat = 0 ;
m_GameStartTime = time_get ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( g_Config . m_Debug )
2010-08-17 22:06:00 +00:00
{
str_format ( aBuf , sizeof ( aBuf ) , " baseline memory usage %dk " , mem_stats ( ) - > allocated / 1024 ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " server " , aBuf ) ;
}
2010-05-29 07:25:38 +00:00
while ( m_RunServer )
{
int64 t = time_get ( ) ;
int NewTicks = 0 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// load new map TODO: don't poll this
2010-05-30 12:01:11 +00:00
if ( str_comp ( g_Config . m_SvMap , m_aCurrentMap ) ! = 0 | | m_MapReload )
2010-05-29 07:25:38 +00:00
{
2010-05-30 12:01:11 +00:00
m_MapReload = 0 ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// load map
if ( LoadMap ( g_Config . m_SvMap ) )
{
2010-07-29 19:55:33 +00:00
Console ( ) - > ExecuteLine ( " tune_reset " , 4 , - 1 ) ;
Console ( ) - > ExecuteLine ( " sv_hit 1 " , 4 , - 1 ) ;
Console ( ) - > ExecuteLine ( " sv_npc 0 " , 4 , - 1 ) ;
Console ( ) - > ExecuteLine ( " sv_phook 1 " , 4 , - 1 ) ;
Console ( ) - > ExecuteLine ( " sv_endless_drag 0 " , 4 , - 1 ) ; //TODO: Such string executed where autoexec executed. No need??
2010-05-29 07:25:38 +00:00
// new map loaded
GameServer ( ) - > OnShutdown ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
for ( int c = 0 ; c < MAX_CLIENTS ; c + + )
{
2010-06-26 15:59:59 +00:00
if ( m_aClients [ c ] . m_State < = CClient : : STATE_AUTH )
2010-05-29 07:25:38 +00:00
continue ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
SendMap ( c ) ;
m_aClients [ c ] . Reset ( ) ;
m_aClients [ c ] . m_State = CClient : : STATE_CONNECTING ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
m_GameStartTime = time_get ( ) ;
m_CurrentGameTick = 0 ;
Kernel ( ) - > ReregisterInterface ( GameServer ( ) ) ;
GameServer ( ) - > OnInit ( ) ;
2010-06-07 11:34:47 +00:00
UpdateServerInfo ( ) ;
2010-05-29 07:25:38 +00:00
}
else
{
2010-08-17 22:06:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " failed to load map. mapname='%s' " , g_Config . m_SvMap ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
str_copy ( g_Config . m_SvMap , m_aCurrentMap , sizeof ( g_Config . m_SvMap ) ) ;
}
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
while ( t > TickStartTime ( m_CurrentGameTick + 1 ) )
{
m_CurrentGameTick + + ;
NewTicks + + ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// apply new input
for ( int c = 0 ; c < MAX_CLIENTS ; c + + )
{
if ( m_aClients [ c ] . m_State = = CClient : : STATE_EMPTY )
continue ;
for ( int i = 0 ; i < 200 ; i + + )
{
if ( m_aClients [ c ] . m_aInputs [ i ] . m_GameTick = = Tick ( ) )
{
if ( m_aClients [ c ] . m_State = = CClient : : STATE_INGAME )
GameServer ( ) - > OnClientPredictedInput ( c , m_aClients [ c ] . m_aInputs [ i ] . m_aData ) ;
break ;
}
}
}
GameServer ( ) - > OnTick ( ) ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// snap game
if ( NewTicks )
{
if ( g_Config . m_SvHighBandwidth | | ( m_CurrentGameTick % 2 ) = = 0 )
DoSnapshot ( ) ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// master server stuff
m_Register . RegisterUpdate ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
PumpNetwork ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( ReportTime < time_get ( ) )
{
if ( g_Config . m_Debug )
{
/*
static NETSTATS prev_stats ;
NETSTATS stats ;
netserver_stats ( net , & stats ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
perf_next ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( config . dbg_pref )
perf_dump ( & rootscope ) ;
dbg_msg ( " server " , " send=%8d recv=%8d " ,
( stats . send_bytes - prev_stats . send_bytes ) / reportinterval ,
( stats . recv_bytes - prev_stats . recv_bytes ) / reportinterval ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
prev_stats = stats ;
*/
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
ReportTime + = time_freq ( ) * ReportInterval ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// wait for incomming data
net_socket_read_wait ( m_NetServer . Socket ( ) , 5 ) ;
}
}
// disconnect all clients on shutdown
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY )
m_NetServer . Drop ( i , " server shutdown " ) ;
}
GameServer ( ) - > OnShutdown ( ) ;
m_pMap - > Unload ( ) ;
if ( m_pCurrentMapData )
mem_free ( m_pCurrentMapData ) ;
return 0 ;
}
2010-07-29 05:21:18 +00:00
void CServer : : ConKick ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
2010-07-29 05:21:18 +00:00
int ClientId1 = pResult - > GetInteger ( 0 ) ;
2010-08-22 16:06:20 +00:00
if ( ClientId = = - 1 | | ( ( CServer * ) pUser ) - > m_aClients [ ClientId ] . m_Authed > ( ( CServer * ) pUser ) - > m_aClients [ ClientId1 ] . m_Authed )
2010-07-29 05:21:18 +00:00
{
char buf [ 128 ] ;
2010-08-22 16:06:20 +00:00
str_format ( buf , sizeof ( buf ) , " Kicked by %s " , ( ( CServer * ) pUser ) - > ClientName ( ClientId ) ) ;
( ( CServer * ) pUser ) - > Kick ( ClientId1 , buf ) ;
}
2010-05-29 07:25:38 +00:00
}
2010-07-29 05:21:18 +00:00
void CServer : : ConBan ( IConsole : : IResult * pResult , void * pUser , int ClientId1 )
2010-05-29 07:25:38 +00:00
{
NETADDR Addr ;
2010-07-29 19:55:33 +00:00
char aAddrStr [ 128 ] , Bufz [ 100 ] ;
2010-09-12 10:07:10 +00:00
CServer * pServer = ( CServer * ) pUser ;
2010-05-29 07:25:38 +00:00
const char * pStr = pResult - > GetString ( 0 ) ;
2010-08-22 16:06:20 +00:00
int Seconds = 30 , jkl ; //????
2010-07-29 19:55:33 +00:00
str_format ( Bufz , sizeof ( Bufz ) , " " ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( pResult - > NumArguments ( ) > 1 )
2010-08-22 16:06:20 +00:00
Seconds = pResult - > GetInteger ( 1 ) ;
2010-07-29 19:55:33 +00:00
if ( pResult - > NumArguments ( ) > 2 )
{
for ( jkl = 2 ; jkl < = pResult - > NumArguments ( ) ; jkl + + )
{
strcat ( Bufz , pResult - > GetString ( jkl ) ) ;
strcat ( Bufz , " " ) ;
}
}
else
2010-08-22 16:06:20 +00:00
str_format ( Bufz , sizeof ( Bufz ) , " no reason given " ) ;
2010-07-29 19:55:33 +00:00
2010-05-29 07:25:38 +00:00
if ( net_addr_from_str ( & Addr , pStr ) = = 0 )
2010-09-12 11:52:25 +00:00
{
if ( pServer - > m_RconClientId > = 0 & & pServer - > m_RconClientId < MAX_CLIENTS & & pServer - > m_aClients [ pServer - > m_RconClientId ] . m_State ! = CClient : : STATE_EMPTY )
{
NETADDR AddrCheck = pServer - > m_NetServer . ClientAddr ( pServer - > m_RconClientId ) ;
Addr . port = AddrCheck . port = 0 ;
if ( net_addr_comp ( & Addr , & AddrCheck ) = = 0 )
{
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " you can't ban yourself " ) ;
return ;
}
}
2010-09-15 15:39:26 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
NETADDR Temp = pServer - > m_NetServer . ClientAddr ( i ) ;
Addr . port = Temp . port = 0 ;
if ( net_addr_comp ( & Addr , & Temp ) = = 0 )
{
if ( ( ( CServer * ) pUser ) - > m_aClients [ ClientId1 ] . m_Authed < = ( ( CServer * ) pUser ) - > m_aClients [ i ] . m_Authed )
{
2010-09-15 15:43:17 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " you can't ban an a player with the higher or same rank! " ) ;
2010-09-15 15:39:26 +00:00
return ;
}
}
}
2010-09-13 04:49:01 +00:00
pServer - > BanAdd ( Addr , Seconds , Bufz ) ;
2010-09-12 11:52:25 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( StrAllnum ( pStr ) )
{
int ClientId = str_toint ( pStr ) ;
2010-07-29 05:21:18 +00:00
if ( ClientId1 ! = - 1 & & ( ( CServer * ) pUser ) - > m_aClients [ ClientId1 ] . m_Authed < = ( ( CServer * ) pUser ) - > m_aClients [ ClientId ] . m_Authed )
2010-08-22 16:06:20 +00:00
return ;
2010-05-29 07:25:38 +00:00
2010-09-12 10:07:10 +00:00
if ( ClientId < 0 | | ClientId > = MAX_CLIENTS | | pServer - > m_aClients [ ClientId ] . m_State = = CClient : : STATE_EMPTY )
2010-05-29 07:25:38 +00:00
{
2010-09-12 10:07:10 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " invalid client id " ) ;
2010-05-29 07:25:38 +00:00
return ;
}
2010-09-12 11:52:25 +00:00
else if ( pServer - > m_RconClientId = = ClientId )
2010-05-29 07:25:38 +00:00
{
2010-09-12 11:52:25 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " you can't ban yourself " ) ;
2010-05-29 07:25:38 +00:00
return ;
}
2010-09-12 10:07:10 +00:00
Addr = pServer - > m_NetServer . ClientAddr ( ClientId ) ;
2010-09-13 04:49:01 +00:00
pServer - > BanAdd ( Addr , Seconds , Bufz ) ;
2010-05-29 07:25:38 +00:00
}
2010-09-12 11:52:25 +00:00
else
{
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " invalid network address to ban " ) ;
return ;
2010-09-12 10:07:10 +00:00
}
2010-05-29 07:25:38 +00:00
Addr . port = 0 ;
net_addr_str ( & Addr , aAddrStr , sizeof ( aAddrStr ) ) ;
2010-08-22 16:06:20 +00:00
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2010-08-22 16:06:20 +00:00
if ( Seconds )
2010-09-15 15:39:26 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " banned %s for %d second(s) " , aAddrStr , Seconds ) ;
2010-05-29 07:25:38 +00:00
else
2010-08-17 22:06:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " banned %s for life " , aAddrStr ) ;
2010-09-12 10:07:10 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
2010-07-29 05:21:18 +00:00
void CServer : : ConUnban ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
NETADDR Addr ;
2010-06-07 12:12:06 +00:00
CServer * pServer = ( CServer * ) pUser ;
2010-05-29 07:25:38 +00:00
const char * pStr = pResult - > GetString ( 0 ) ;
2010-08-22 16:06:20 +00:00
2010-08-17 22:06:00 +00:00
if ( net_addr_from_str ( & Addr , pStr ) = = 0 & & ! pServer - > BanRemove ( Addr ) )
{
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " unbanned %d.%d.%d.%d " , Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] ) ;
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
}
2010-06-07 12:12:06 +00:00
else if ( StrAllnum ( pStr ) )
{
int BanIndex = str_toint ( pStr ) ;
CNetServer : : CBanInfo Info ;
if ( BanIndex < 0 | | ! pServer - > m_NetServer . BanGet ( BanIndex , & Info ) )
2010-08-17 22:06:00 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " invalid ban index " ) ;
else if ( ! pServer - > BanRemove ( Info . m_Addr ) )
{
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " unbanned %d.%d.%d.%d " , Info . m_Addr . ip [ 0 ] , Info . m_Addr . ip [ 1 ] , Info . m_Addr . ip [ 2 ] , Info . m_Addr . ip [ 3 ] ) ;
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
}
2010-06-07 12:12:06 +00:00
}
2010-05-29 07:25:38 +00:00
else
2010-08-17 22:06:00 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " invalid network address " ) ;
2010-05-29 07:25:38 +00:00
}
2010-07-29 05:21:18 +00:00
void CServer : : ConBans ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
unsigned Now = time_timestamp ( ) ;
char aBuf [ 1024 ] ;
CServer * pServer = ( CServer * ) pUser ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
int Num = pServer - > m_NetServer . BanNum ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < Num ; i + + )
{
CNetServer : : CBanInfo Info ;
pServer - > m_NetServer . BanGet ( i , & Info ) ;
NETADDR Addr = Info . m_Addr ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( Info . m_Expires = = - 1 )
{
str_format ( aBuf , sizeof ( aBuf ) , " #%d %d.%d.%d.%d for life " , i , Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] ) ;
}
else
{
unsigned t = Info . m_Expires - Now ;
str_format ( aBuf , sizeof ( aBuf ) , " #%d %d.%d.%d.%d for %d minutes and %d seconds " , i , Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] , t / 60 , t % 60 ) ;
}
2010-08-17 22:06:00 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " Server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
str_format ( aBuf , sizeof ( aBuf ) , " %d ban(s) " , Num ) ;
2010-08-17 22:06:00 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " Server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
2010-07-29 05:21:18 +00:00
void CServer : : ConStatus ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
int i ;
NETADDR Addr ;
char aBuf [ 1024 ] ;
CServer * pServer = ( CServer * ) pUser ;
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
2010-06-03 12:48:32 +00:00
if ( pServer - > m_aClients [ i ] . m_State ! = CClient : : STATE_EMPTY )
2010-05-29 07:25:38 +00:00
{
Addr = pServer - > m_NetServer . ClientAddr ( i ) ;
2010-06-03 12:48:32 +00:00
if ( pServer - > m_aClients [ i ] . m_State = = CClient : : STATE_INGAME )
2010-07-30 20:16:36 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " id=%d addr=%d.%d.%d.%d:%d name='%s' level=%d " ,
2010-06-03 12:48:32 +00:00
i , Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] , Addr . port ,
2010-07-30 20:16:36 +00:00
pServer - > m_aClients [ i ] . m_aName , pServer - > m_aClients [ i ] . m_Authed ) ;
2010-06-03 12:48:32 +00:00
else
str_format ( aBuf , sizeof ( aBuf ) , " id=%d addr=%d.%d.%d.%d:%d connecting " ,
i , Addr . ip [ 0 ] , Addr . ip [ 1 ] , Addr . ip [ 2 ] , Addr . ip [ 3 ] , Addr . port ) ;
2010-08-17 22:06:00 +00:00
pServer - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " Server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
}
}
2010-07-29 05:21:18 +00:00
void CServer : : ConShutdown ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
( ( CServer * ) pUser ) - > m_RunServer = 0 ;
}
2010-07-29 05:21:18 +00:00
void CServer : : ConRecord ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
char aFilename [ 512 ] ;
str_format ( aFilename , sizeof ( aFilename ) , " demos/%s.demo " , pResult - > GetString ( 0 ) ) ;
2010-08-17 22:06:00 +00:00
( ( CServer * ) pUser ) - > m_DemoRecorder . Start ( ( ( CServer * ) pUser ) - > Storage ( ) , ( ( CServer * ) pUser ) - > Console ( ) , aFilename , ( ( CServer * ) pUser ) - > GameServer ( ) - > NetVersion ( ) , ( ( CServer * ) pUser ) - > m_aCurrentMap , ( ( CServer * ) pUser ) - > m_CurrentMapCrc , " server " ) ;
2010-05-29 07:25:38 +00:00
}
2010-07-29 05:21:18 +00:00
void CServer : : ConStopRecord ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-29 07:25:38 +00:00
{
( ( CServer * ) pUser ) - > m_DemoRecorder . Stop ( ) ;
}
2010-07-29 05:21:18 +00:00
void CServer : : ConMapReload ( IConsole : : IResult * pResult , void * pUser , int ClientId )
2010-05-30 12:01:11 +00:00
{
( ( CServer * ) pUser ) - > m_MapReload = 1 ;
}
2010-05-29 07:25:38 +00:00
void CServer : : ConchainSpecialInfoupdate ( IConsole : : IResult * pResult , void * pUserData , IConsole : : FCommandCallback pfnCallback , void * pCallbackUserData )
{
2010-07-29 05:21:18 +00:00
pfnCallback ( pResult , pCallbackUserData , - 1 ) ;
2010-05-29 07:25:38 +00:00
if ( pResult - > NumArguments ( ) )
( ( CServer * ) pUserData ) - > UpdateServerInfo ( ) ;
}
2010-06-03 12:48:32 +00:00
void CServer : : ConchainMaxclientsperipUpdate ( IConsole : : IResult * pResult , void * pUserData , IConsole : : FCommandCallback pfnCallback , void * pCallbackUserData )
{
2010-07-29 05:21:18 +00:00
pfnCallback ( pResult , pCallbackUserData , - 1 ) ;
2010-06-03 12:48:32 +00:00
if ( pResult - > NumArguments ( ) )
( ( CServer * ) pUserData ) - > m_NetServer . SetMaxClientsPerIP ( pResult - > GetInteger ( 0 ) ) ;
}
2010-05-29 07:25:38 +00:00
void CServer : : RegisterCommands ( )
{
m_pConsole = Kernel ( ) - > RequestInterface < IConsole > ( ) ;
2010-08-22 16:06:20 +00:00
2010-07-29 05:21:18 +00:00
Console ( ) - > Register ( " kick " , " i " , CFGFLAG_SERVER , ConKick , this , " " , 2 ) ;
2010-08-22 16:06:20 +00:00
Console ( ) - > Register ( " ban " , " s?i?r " , CFGFLAG_SERVER , ConBan , this , " Ban player " , 2 ) ; //horrible long string
2010-07-29 05:21:18 +00:00
Console ( ) - > Register ( " unban " , " s " , CFGFLAG_SERVER , ConUnban , this , " " , 3 ) ;
Console ( ) - > Register ( " bans " , " " , CFGFLAG_SERVER , ConBans , this , " " , 2 ) ;
Console ( ) - > Register ( " status " , " " , CFGFLAG_SERVER , ConStatus , this , " " , 1 ) ;
Console ( ) - > Register ( " shutdown " , " " , CFGFLAG_SERVER , ConShutdown , this , " " , 3 ) ;
Console ( ) - > Register ( " record " , " s " , CFGFLAG_SERVER , ConRecord , this , " " , 3 ) ;
Console ( ) - > Register ( " stoprecord " , " " , CFGFLAG_SERVER , ConStopRecord , this , " " , 3 ) ;
Console ( ) - > Register ( " reload " , " " , CFGFLAG_SERVER , ConMapReload , this , " " , 3 ) ;
2010-05-29 07:25:38 +00:00
Console ( ) - > Chain ( " sv_name " , ConchainSpecialInfoupdate , this ) ;
Console ( ) - > Chain ( " password " , ConchainSpecialInfoupdate , this ) ;
2010-06-03 12:48:32 +00:00
Console ( ) - > Chain ( " sv_max_clients_per_ip " , ConchainMaxclientsperipUpdate , this ) ;
2010-08-22 16:06:20 +00:00
}
2010-05-29 07:25:38 +00:00
int CServer : : SnapNewID ( )
{
return m_IDPool . NewID ( ) ;
}
void CServer : : SnapFreeID ( int ID )
{
m_IDPool . FreeID ( ID ) ;
}
void * CServer : : SnapNewItem ( int Type , int Id , int Size )
{
dbg_assert ( Type > = 0 & & Type < = 0xffff , " incorrect type " ) ;
dbg_assert ( Id > = 0 & & Id < = 0xffff , " incorrect id " ) ;
2010-08-22 16:06:20 +00:00
return m_SnapshotBuilder . NewItem ( Type , Id , Size ) ;
2010-05-29 07:25:38 +00:00
}
void CServer : : SnapSetStaticsize ( int ItemType , int Size )
{
m_SnapshotDelta . SetStaticsize ( ItemType , Size ) ;
}
static CServer * CreateServer ( ) { return new CServer ( ) ; }
int main ( int argc , const char * * argv ) // ignore_convention
{
# if defined(CONF_FAMILY_WINDOWS)
for ( int i = 1 ; i < argc ; i + + ) // ignore_convention
{
if ( str_comp ( " -s " , argv [ i ] ) = = 0 | | str_comp ( " --silent " , argv [ i ] ) = = 0 ) // ignore_convention
{
ShowWindow ( GetConsoleWindow ( ) , SW_HIDE ) ;
break ;
}
}
# endif
// init the engine
dbg_msg ( " server " , " starting... " ) ;
CServer * pServer = CreateServer ( ) ;
pServer - > InitEngine ( " Teeworlds " ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
IKernel * pKernel = IKernel : : Create ( ) ;
// create the components
IEngineMap * pEngineMap = CreateEngineMap ( ) ;
IGameServer * pGameServer = CreateGameServer ( ) ;
2010-06-18 18:32:52 +00:00
IConsole * pConsole = CreateConsole ( CFGFLAG_SERVER ) ;
2010-05-29 07:25:38 +00:00
IEngineMasterServer * pEngineMasterServer = CreateEngineMasterServer ( ) ;
2010-08-05 18:26:03 +00:00
IStorage * pStorage = CreateStorage ( " Teeworlds " , argc , argv ) ; // ignore_convention
2010-05-29 07:25:38 +00:00
IConfig * pConfig = CreateConfig ( ) ;
2010-08-22 16:06:20 +00:00
2010-08-17 22:06:00 +00:00
pServer - > InitRegister ( & pServer - > m_NetServer , pEngineMasterServer , pConsole ) ;
2010-05-29 07:25:38 +00:00
{
bool RegisterFail = false ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pServer ) ; // register as both
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( static_cast < IEngineMap * > ( pEngineMap ) ) ; // register as both
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( static_cast < IMap * > ( pEngineMap ) ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pGameServer ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pConsole ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pStorage ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pConfig ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( static_cast < IEngineMasterServer * > ( pEngineMasterServer ) ) ; // register as both
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( static_cast < IMasterServer * > ( pEngineMasterServer ) ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
if ( RegisterFail )
return - 1 ;
}
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
pConfig - > Init ( ) ;
pEngineMasterServer - > Init ( pServer - > Engine ( ) ) ;
pEngineMasterServer - > Load ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// register all console commands
pServer - > RegisterCommands ( ) ;
pGameServer - > OnConsoleInit ( ) ;
2010-08-22 16:06:20 +00:00
2010-07-29 19:55:33 +00:00
pConsole - > ExecuteLine ( " tune_reset " , 4 , - 1 ) ;
pConsole - > ExecuteLine ( " sv_hit 1 " , 4 , - 1 ) ;
pConsole - > ExecuteLine ( " sv_npc 0 " , 4 , - 1 ) ;
pConsole - > ExecuteLine ( " sv_phook 1 " , 4 , - 1 ) ;
pConsole - > ExecuteLine ( " sv_endless_drag 0 " , 4 , - 1 ) ;
2010-08-22 16:06:20 +00:00
2010-07-31 11:04:19 +00:00
2010-07-29 19:55:33 +00:00
//TODO it is in 2 places (and in one file O_o)
2010-05-29 07:25:38 +00:00
// execute autoexec file
pConsole - > ExecuteFile ( " autoexec.cfg " ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// parse the command line arguments
if ( argc > 1 ) // ignore_convention
pConsole - > ParseArguments ( argc - 1 , & argv [ 1 ] ) ; // ignore_convention
2010-08-10 22:31:42 +00:00
// restore empty config strings to their defaults
pConfig - > RestoreStrings ( ) ;
2010-08-22 16:06:20 +00:00
2010-08-06 18:38:13 +00:00
pServer - > Engine ( ) - > InitLogfile ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// run the server
pServer - > Run ( ) ;
2010-08-22 16:06:20 +00:00
2010-05-29 07:25:38 +00:00
// free
delete pServer ;
delete pKernel ;
delete pEngineMap ;
delete pGameServer ;
delete pConsole ;
delete pEngineMasterServer ;
delete pStorage ;
delete pConfig ;
return 0 ;
}
2010-09-17 14:23:07 +00:00
void CServer : : SetRconLevel ( int ClientId , int Level )
2010-09-17 13:47:31 +00:00
{
2010-09-17 14:23:07 +00:00
if ( ! Level )
2010-09-17 13:47:31 +00:00
{
2010-09-17 14:23:07 +00:00
dbg_msg ( " server " , " %s set to level 0. ClientId=%x ip=%d.%d.%d.%d " , ClientName ( ClientId ) , ClientId , m_aClients [ ClientId ] . m_Addr . ip [ 0 ] , m_aClients [ ClientId ] . m_Addr . ip [ 1 ] , m_aClients [ ClientId ] . m_Addr . ip [ 2 ] , m_aClients [ ClientId ] . m_Addr . ip [ 3 ] ) ;
2010-09-17 13:47:31 +00:00
CMsgPacker Msg ( NETMSG_RCON_AUTH_STATUS ) ;
Msg . AddInt ( 0 ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL , ClientId , true ) ;
m_aClients [ ClientId ] . m_Authed = 0 ;
}
2010-09-17 14:23:07 +00:00
else
{
dbg_msg ( " server " , " %s set to level %d. ClientId=%x ip=%d.%d.%d.%d " , ClientName ( ClientId ) , Level , ClientId , m_aClients [ ClientId ] . m_Addr . ip [ 0 ] , m_aClients [ ClientId ] . m_Addr . ip [ 1 ] , m_aClients [ ClientId ] . m_Addr . ip [ 2 ] , m_aClients [ ClientId ] . m_Addr . ip [ 3 ] ) ;
CMsgPacker Msg ( NETMSG_RCON_AUTH_STATUS ) ;
Msg . AddInt ( 1 ) ;
SendMsgEx ( & Msg , MSGFLAG_VITAL , ClientId , true ) ;
m_aClients [ ClientId ] . m_Authed = Level ;
}
2010-09-17 13:47:31 +00:00
}