2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2008-09-23 07:43:41 +00:00
# include <new>
2010-05-29 07:25:38 +00:00
# include <base/math.h>
# include <engine/shared/config.h>
# include <engine/map.h>
# include <engine/console.h>
# include "gamecontext.h"
# include <game/version.h>
# include <game/collision.h>
# include <game/gamecore.h>
# include "gamemodes/dm.h"
# include "gamemodes/tdm.h"
# include "gamemodes/ctf.h"
# include "gamemodes/mod.h"
2008-08-14 18:42:47 +00:00
2010-05-29 07:25:38 +00:00
enum
{
RESET ,
NO_RESET
} ;
2008-08-14 18:42:47 +00:00
2010-05-29 07:25:38 +00:00
void CGameContext : : Construct ( int Resetting )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
m_Resetting = 0 ;
m_pServer = 0 ;
2008-09-23 07:43:41 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
2010-05-29 07:25:38 +00:00
m_apPlayers [ i ] = 0 ;
2009-01-12 21:44:13 +00:00
2010-05-29 07:25:38 +00:00
m_pController = 0 ;
m_VoteCloseTime = 0 ;
m_pVoteOptionFirst = 0 ;
m_pVoteOptionLast = 0 ;
if ( Resetting = = NO_RESET )
m_pVoteOptionHeap = new CHeap ( ) ;
}
CGameContext : : CGameContext ( int Resetting )
{
Construct ( Resetting ) ;
}
CGameContext : : CGameContext ( )
{
Construct ( NO_RESET ) ;
2008-09-23 07:43:41 +00:00
}
2010-05-29 07:25:38 +00:00
CGameContext : : ~ CGameContext ( )
2008-09-23 07:43:41 +00:00
{
2008-09-24 09:03:49 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
2010-05-29 07:25:38 +00:00
delete m_apPlayers [ i ] ;
if ( ! m_Resetting )
delete m_pVoteOptionHeap ;
2008-08-14 18:42:47 +00:00
}
2010-05-29 07:25:38 +00:00
void CGameContext : : Clear ( )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
CHeap * pVoteOptionHeap = m_pVoteOptionHeap ;
CVoteOption * pVoteOptionFirst = m_pVoteOptionFirst ;
CVoteOption * pVoteOptionLast = m_pVoteOptionLast ;
CTuningParams Tuning = m_Tuning ;
m_Resetting = true ;
this - > ~ CGameContext ( ) ;
2008-09-23 07:43:41 +00:00
mem_zero ( this , sizeof ( * this ) ) ;
2010-05-29 07:25:38 +00:00
new ( this ) CGameContext ( RESET ) ;
m_pVoteOptionHeap = pVoteOptionHeap ;
m_pVoteOptionFirst = pVoteOptionFirst ;
m_pVoteOptionLast = pVoteOptionLast ;
m_Tuning = Tuning ;
2008-08-14 18:42:47 +00:00
}
2011-02-12 10:40:36 +00:00
class CCharacter * CGameContext : : GetPlayerChar ( int ClientID )
2008-10-20 23:00:46 +00:00
{
2011-02-12 10:40:36 +00:00
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS | | ! m_apPlayers [ ClientID ] )
2008-10-20 23:00:46 +00:00
return 0 ;
2011-02-12 10:40:36 +00:00
return m_apPlayers [ ClientID ] - > GetCharacter ( ) ;
2008-10-20 23:00:46 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : CreateDamageInd ( vec2 Pos , float Angle , int Amount )
2008-08-14 18:42:47 +00:00
{
2011-02-13 06:47:51 +00:00
float a = 3 * 3.14159f / 2 + Angle ;
2008-08-14 18:42:47 +00:00
//float a = get_angle(dir);
2011-02-13 06:47:51 +00:00
float s = a - pi / 3 ;
float e = a + pi / 3 ;
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < Amount ; i + + )
2008-08-14 18:42:47 +00:00
{
2011-02-13 06:47:51 +00:00
float f = mix ( s , e , float ( i + 1 ) / float ( Amount + 2 ) ) ;
2011-02-12 10:40:36 +00:00
NETEVENT_DAMAGEIND * pEvent = ( NETEVENT_DAMAGEIND * ) m_Events . Create ( NETEVENTTYPE_DAMAGEIND , sizeof ( NETEVENT_DAMAGEIND ) ) ;
if ( pEvent )
2008-08-14 18:42:47 +00:00
{
2011-02-12 10:40:36 +00:00
pEvent - > m_X = ( int ) Pos . x ;
pEvent - > m_Y = ( int ) Pos . y ;
2011-02-13 06:47:51 +00:00
pEvent - > m_Angle = ( int ) ( f * 256.0f ) ;
2008-08-14 18:42:47 +00:00
}
}
}
2011-02-12 10:40:36 +00:00
void CGameContext : : CreateHammerHit ( vec2 Pos )
2008-10-17 11:23:21 +00:00
{
// create the event
2011-02-12 10:40:36 +00:00
NETEVENT_HAMMERHIT * pEvent = ( NETEVENT_HAMMERHIT * ) m_Events . Create ( NETEVENTTYPE_HAMMERHIT , sizeof ( NETEVENT_HAMMERHIT ) ) ;
if ( pEvent )
2008-10-17 11:23:21 +00:00
{
2011-02-12 10:40:36 +00:00
pEvent - > m_X = ( int ) Pos . x ;
pEvent - > m_Y = ( int ) Pos . y ;
2008-10-17 11:23:21 +00:00
}
}
2011-02-12 10:40:36 +00:00
void CGameContext : : CreateExplosion ( vec2 Pos , int Owner , int Weapon , bool NoDamage )
2008-08-14 18:42:47 +00:00
{
// create the event
2011-02-12 10:40:36 +00:00
NETEVENT_EXPLOSION * pEvent = ( NETEVENT_EXPLOSION * ) m_Events . Create ( NETEVENTTYPE_EXPLOSION , sizeof ( NETEVENT_EXPLOSION ) ) ;
if ( pEvent )
2008-08-14 18:42:47 +00:00
{
2011-02-12 10:40:36 +00:00
pEvent - > m_X = ( int ) Pos . x ;
pEvent - > m_Y = ( int ) Pos . y ;
2008-08-14 18:42:47 +00:00
}
2010-05-29 07:25:38 +00:00
if ( ! NoDamage )
2008-08-14 18:42:47 +00:00
{
// deal damage
2011-01-19 17:27:50 +00:00
CCharacter * apEnts [ MAX_CLIENTS ] ;
2010-05-29 07:25:38 +00:00
float Radius = 135.0f ;
float InnerRadius = 48.0f ;
2011-02-12 10:40:36 +00:00
int Num = m_World . FindEntities ( Pos , Radius , ( CEntity * * ) apEnts , MAX_CLIENTS , CGameWorld : : ENTTYPE_CHARACTER ) ;
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < Num ; i + + )
2008-08-14 18:42:47 +00:00
{
2011-02-12 10:40:36 +00:00
vec2 Diff = apEnts [ i ] - > m_Pos - Pos ;
2010-05-29 07:25:38 +00:00
vec2 ForceDir ( 0 , 1 ) ;
float l = length ( Diff ) ;
2008-08-14 18:42:47 +00:00
if ( l )
2010-05-29 07:25:38 +00:00
ForceDir = normalize ( Diff ) ;
l = 1 - clamp ( ( l - InnerRadius ) / ( Radius - InnerRadius ) , 0.0f , 1.0f ) ;
float Dmg = 6 * l ;
if ( ( int ) Dmg )
apEnts [ i ] - > TakeDamage ( ForceDir * Dmg * 2 , ( int ) Dmg , Owner , Weapon ) ;
2008-08-14 18:42:47 +00:00
}
}
}
/*
2011-02-13 06:47:51 +00:00
void create_smoke ( vec2 Pos )
2008-08-14 18:42:47 +00:00
{
// create the event
2011-02-12 10:40:36 +00:00
EV_EXPLOSION * pEvent = ( EV_EXPLOSION * ) events . create ( EVENT_SMOKE , sizeof ( EV_EXPLOSION ) ) ;
if ( pEvent )
2008-08-14 18:42:47 +00:00
{
2011-02-13 06:47:51 +00:00
pEvent - > x = ( int ) Pos . x ;
pEvent - > y = ( int ) Pos . y ;
2008-08-14 18:42:47 +00:00
}
} */
2011-02-12 10:40:36 +00:00
void CGameContext : : CreatePlayerSpawn ( vec2 Pos )
2008-08-14 18:42:47 +00:00
{
// create the event
2010-05-29 07:25:38 +00:00
NETEVENT_SPAWN * ev = ( NETEVENT_SPAWN * ) m_Events . Create ( NETEVENTTYPE_SPAWN , sizeof ( NETEVENT_SPAWN ) ) ;
2008-08-14 18:42:47 +00:00
if ( ev )
{
2011-02-12 10:40:36 +00:00
ev - > m_X = ( int ) Pos . x ;
ev - > m_Y = ( int ) Pos . y ;
2008-08-14 18:42:47 +00:00
}
}
2011-02-12 10:40:36 +00:00
void CGameContext : : CreateDeath ( vec2 Pos , int ClientID )
2008-08-14 18:42:47 +00:00
{
// create the event
2011-02-12 10:40:36 +00:00
NETEVENT_DEATH * pEvent = ( NETEVENT_DEATH * ) m_Events . Create ( NETEVENTTYPE_DEATH , sizeof ( NETEVENT_DEATH ) ) ;
if ( pEvent )
2008-08-14 18:42:47 +00:00
{
2011-02-12 10:40:36 +00:00
pEvent - > m_X = ( int ) Pos . x ;
pEvent - > m_Y = ( int ) Pos . y ;
pEvent - > m_ClientID = ClientID ;
2008-08-14 18:42:47 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CGameContext : : CreateSound ( vec2 Pos , int Sound , int Mask )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
if ( Sound < 0 )
2008-08-14 18:42:47 +00:00
return ;
// create a sound
2011-02-12 10:40:36 +00:00
NETEVENT_SOUNDWORLD * pEvent = ( NETEVENT_SOUNDWORLD * ) m_Events . Create ( NETEVENTTYPE_SOUNDWORLD , sizeof ( NETEVENT_SOUNDWORLD ) , Mask ) ;
if ( pEvent )
2008-08-14 18:42:47 +00:00
{
2011-02-12 10:40:36 +00:00
pEvent - > m_X = ( int ) Pos . x ;
pEvent - > m_Y = ( int ) Pos . y ;
pEvent - > m_SoundID = Sound ;
2008-08-14 18:42:47 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CGameContext : : CreateSoundGlobal ( int Sound , int Target )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
if ( Sound < 0 )
2008-08-14 18:42:47 +00:00
return ;
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_SoundGlobal Msg ;
2011-02-12 10:40:36 +00:00
Msg . m_SoundID = Sound ;
2010-05-29 07:25:38 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , Target ) ;
2008-08-14 18:42:47 +00:00
}
2009-01-11 14:28:35 +00:00
2010-05-29 07:25:38 +00:00
void CGameContext : : SendChatTarget ( int To , const char * pText )
2009-01-11 14:28:35 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_Chat Msg ;
Msg . m_Team = 0 ;
2011-02-12 10:40:36 +00:00
Msg . m_ClientID = - 1 ;
2010-05-29 07:25:38 +00:00
Msg . m_pMessage = pText ;
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , To ) ;
2009-01-11 14:28:35 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendChat ( int ChatterClientID , int Team , const char * pText )
2008-08-14 18:42:47 +00:00
{
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2011-02-12 10:40:36 +00:00
if ( ChatterClientID > = 0 & & ChatterClientID < MAX_CLIENTS )
str_format ( aBuf , sizeof ( aBuf ) , " %d:%d:%s: %s " , ChatterClientID , Team , Server ( ) - > ClientName ( ChatterClientID ) , pText ) ;
2008-08-14 18:42:47 +00:00
else
2010-08-17 22:06:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " *** %s " , pText ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " chat " , aBuf ) ;
2008-08-14 18:42:47 +00:00
2010-05-29 07:25:38 +00:00
if ( Team = = CHAT_ALL )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_Chat Msg ;
Msg . m_Team = 0 ;
2011-02-12 10:40:36 +00:00
Msg . m_ClientID = ChatterClientID ;
2010-05-29 07:25:38 +00:00
Msg . m_pMessage = pText ;
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , - 1 ) ;
2008-08-14 18:42:47 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_Chat Msg ;
Msg . m_Team = 1 ;
2011-02-12 10:40:36 +00:00
Msg . m_ClientID = ChatterClientID ;
2010-05-29 07:25:38 +00:00
Msg . m_pMessage = pText ;
2009-06-15 13:01:04 +00:00
// pack one for the recording only
2010-05-29 07:25:38 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NOSEND , - 1 ) ;
2008-08-14 18:42:47 +00:00
2009-06-15 13:01:04 +00:00
// send to the clients
2008-08-14 18:42:47 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
2010-05-29 07:25:38 +00:00
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > GetTeam ( ) = = Team )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NORECORD , i ) ;
2008-08-14 18:42:47 +00:00
}
}
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendEmoticon ( int ClientID , int Emoticon )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_Emoticon Msg ;
2011-02-12 10:40:36 +00:00
Msg . m_ClientID = ClientID ;
2010-05-29 07:25:38 +00:00
Msg . m_Emoticon = Emoticon ;
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , - 1 ) ;
2008-08-14 18:42:47 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendWeaponPickup ( int ClientID , int Weapon )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_WeaponPickup Msg ;
Msg . m_Weapon = Weapon ;
2011-02-12 10:40:36 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2008-08-14 18:42:47 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendBroadcast ( const char * pText , int ClientID )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_Broadcast Msg ;
Msg . m_pMessage = pText ;
2011-02-12 10:40:36 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2008-08-14 18:42:47 +00:00
}
2008-09-24 14:47:03 +00:00
//
2011-03-25 09:26:59 +00:00
void CGameContext : : StartVote ( const char * pDesc , const char * pCommand , const char * pReason )
2008-09-24 14:47:03 +00:00
{
// check if a vote is already running
2010-05-29 07:25:38 +00:00
if ( m_VoteCloseTime )
2008-09-24 14:47:03 +00:00
return ;
// reset votes
2010-05-29 07:25:38 +00:00
m_VoteEnforce = VOTE_ENFORCE_UNKNOWN ;
2008-09-24 14:47:03 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
2010-05-29 07:25:38 +00:00
if ( m_apPlayers [ i ] )
{
m_apPlayers [ i ] - > m_Vote = 0 ;
m_apPlayers [ i ] - > m_VotePos = 0 ;
}
2008-09-24 14:47:03 +00:00
}
// start vote
2010-05-29 07:25:38 +00:00
m_VoteCloseTime = time_get ( ) + time_freq ( ) * 25 ;
str_copy ( m_aVoteDescription , pDesc , sizeof ( m_aVoteDescription ) ) ;
str_copy ( m_aVoteCommand , pCommand , sizeof ( m_aVoteCommand ) ) ;
2011-03-25 09:26:59 +00:00
str_copy ( m_aVoteReason , pReason , sizeof ( m_aVoteReason ) ) ;
2010-05-29 07:25:38 +00:00
SendVoteSet ( - 1 ) ;
m_VoteUpdate = true ;
2008-09-24 14:47:03 +00:00
}
2008-09-25 12:41:37 +00:00
2010-05-29 07:25:38 +00:00
void CGameContext : : EndVote ( )
2008-09-25 12:41:37 +00:00
{
2010-05-29 07:25:38 +00:00
m_VoteCloseTime = 0 ;
SendVoteSet ( - 1 ) ;
2008-09-25 12:41:37 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendVoteSet ( int ClientID )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_VoteSet Msg ;
if ( m_VoteCloseTime )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
Msg . m_Timeout = ( m_VoteCloseTime - time_get ( ) ) / time_freq ( ) ;
Msg . m_pDescription = m_aVoteDescription ;
2011-03-25 09:26:59 +00:00
Msg . m_pReason = m_aVoteReason ;
2008-09-24 14:47:03 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
Msg . m_Timeout = 0 ;
Msg . m_pDescription = " " ;
2011-03-25 09:26:59 +00:00
Msg . m_pReason = " " ;
2008-09-24 14:47:03 +00:00
}
2011-02-12 10:40:36 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2008-09-24 14:47:03 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendVoteStatus ( int ClientID , int Total , int Yes , int No )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_VoteStatus Msg = { 0 } ;
Msg . m_Total = Total ;
Msg . m_Yes = Yes ;
Msg . m_No = No ;
Msg . m_Pass = Total - ( Yes + No ) ;
2011-02-12 10:40:36 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : AbortVoteKickOnDisconnect ( int ClientID )
2010-05-29 07:25:38 +00:00
{
2011-02-12 10:40:36 +00:00
if ( m_VoteCloseTime & & ! str_comp_num ( m_aVoteCommand , " kick " , 5 ) & & str_toint ( & m_aVoteCommand [ 5 ] ) = = ClientID )
2010-05-29 07:25:38 +00:00
m_VoteCloseTime = - 1 ;
}
void CGameContext : : CheckPureTuning ( )
{
// might not be created yet during start up
if ( ! m_pController )
return ;
if ( str_comp ( m_pController - > m_pGameType , " DM " ) = = 0 | |
str_comp ( m_pController - > m_pGameType , " TDM " ) = = 0 | |
str_comp ( m_pController - > m_pGameType , " CTF " ) = = 0 )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
CTuningParams p ;
if ( mem_comp ( & p , & m_Tuning , sizeof ( p ) ) ! = 0 )
2008-09-24 14:47:03 +00:00
{
2010-08-17 22:06:00 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " resetting tuning due to pure server " ) ;
2010-05-29 07:25:38 +00:00
m_Tuning = p ;
2008-09-24 14:47:03 +00:00
}
}
}
2011-02-12 10:40:36 +00:00
void CGameContext : : SendTuningParams ( int ClientID )
2008-10-21 17:26:32 +00:00
{
2010-05-29 07:25:38 +00:00
CheckPureTuning ( ) ;
CMsgPacker Msg ( NETMSGTYPE_SV_TUNEPARAMS ) ;
int * pParams = ( int * ) & m_Tuning ;
for ( unsigned i = 0 ; i < sizeof ( m_Tuning ) / sizeof ( int ) ; i + + )
Msg . AddInt ( pParams [ i ] ) ;
2011-02-12 10:40:36 +00:00
Server ( ) - > SendMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2008-10-21 17:26:32 +00:00
}
2010-05-29 07:25:38 +00:00
void CGameContext : : OnTick ( )
2008-08-14 18:42:47 +00:00
{
2010-05-29 07:25:38 +00:00
// check tuning
CheckPureTuning ( ) ;
// copy tuning
m_World . m_Core . m_Tuning = m_Tuning ;
m_World . Tick ( ) ;
2008-08-14 18:42:47 +00:00
//if(world.paused) // make sure that the game object always updates
2010-05-29 07:25:38 +00:00
m_pController - > Tick ( ) ;
2008-08-14 18:42:47 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
2010-05-29 07:25:38 +00:00
if ( m_apPlayers [ i ] )
2011-03-10 09:08:14 +00:00
{
2010-05-29 07:25:38 +00:00
m_apPlayers [ i ] - > Tick ( ) ;
2011-03-10 09:08:14 +00:00
m_apPlayers [ i ] - > PostTick ( ) ;
}
2008-08-14 18:42:47 +00:00
}
2008-09-24 14:47:03 +00:00
// update voting
2010-05-29 07:25:38 +00:00
if ( m_VoteCloseTime )
2008-09-24 14:47:03 +00:00
{
2008-10-21 17:26:32 +00:00
// abort the kick-vote on player-leave
2010-05-29 07:25:38 +00:00
if ( m_VoteCloseTime = = - 1 )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote aborted " ) ;
EndVote ( ) ;
2008-10-21 17:26:32 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
int Total = 0 , Yes = 0 , No = 0 ;
if ( m_VoteUpdate )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
// count votes
char aaBuf [ MAX_CLIENTS ] [ 64 ] = { { 0 } } ;
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
if ( m_apPlayers [ i ] )
Server ( ) - > GetClientIP ( i , aaBuf [ i ] , 64 ) ;
bool aVoteChecked [ MAX_CLIENTS ] = { 0 } ;
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
2008-10-21 17:26:32 +00:00
{
2011-01-03 11:50:38 +00:00
if ( ! m_apPlayers [ i ] | | m_apPlayers [ i ] - > GetTeam ( ) = = TEAM_SPECTATORS | | aVoteChecked [ i ] ) // don't count in votes by spectators
2010-05-29 07:25:38 +00:00
continue ;
int ActVote = m_apPlayers [ i ] - > m_Vote ;
int ActVotePos = m_apPlayers [ i ] - > m_VotePos ;
// check for more players with the same ip (only use the vote of the one who voted first)
for ( int j = i + 1 ; j < MAX_CLIENTS ; + + j )
{
if ( ! m_apPlayers [ j ] | | aVoteChecked [ j ] | | str_comp ( aaBuf [ j ] , aaBuf [ i ] ) )
continue ;
aVoteChecked [ j ] = true ;
if ( m_apPlayers [ j ] - > m_Vote & & ( ! ActVote | | ActVotePos > m_apPlayers [ j ] - > m_VotePos ) )
{
ActVote = m_apPlayers [ j ] - > m_Vote ;
ActVotePos = m_apPlayers [ j ] - > m_VotePos ;
}
}
Total + + ;
if ( ActVote > 0 )
Yes + + ;
else if ( ActVote < 0 )
No + + ;
2008-10-21 17:26:32 +00:00
}
2010-05-29 07:25:38 +00:00
if ( Yes > = Total / 2 + 1 )
m_VoteEnforce = VOTE_ENFORCE_YES ;
2010-09-12 10:51:07 +00:00
else if ( No > = ( Total + 1 ) / 2 )
2010-05-29 07:25:38 +00:00
m_VoteEnforce = VOTE_ENFORCE_NO ;
2008-09-24 14:47:03 +00:00
}
2010-05-29 07:25:38 +00:00
if ( m_VoteEnforce = = VOTE_ENFORCE_YES )
{
Console ( ) - > ExecuteLine ( m_aVoteCommand ) ;
EndVote ( ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote passed " ) ;
if ( m_apPlayers [ m_VoteCreator ] )
2011-03-10 09:08:14 +00:00
m_apPlayers [ m_VoteCreator ] - > m_LastVoteCall = 0 ;
2010-05-29 07:25:38 +00:00
}
else if ( m_VoteEnforce = = VOTE_ENFORCE_NO | | time_get ( ) > m_VoteCloseTime )
{
EndVote ( ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote failed " ) ;
}
else if ( m_VoteUpdate )
{
m_VoteUpdate = false ;
SendVoteStatus ( - 1 , Total , Yes , No ) ;
}
}
}
# ifdef CONF_DEBUG
if ( g_Config . m_DbgDummies )
{
for ( int i = 0 ; i < g_Config . m_DbgDummies ; i + + )
{
CNetObj_PlayerInput Input = { 0 } ;
Input . m_Direction = ( i & 1 ) ? - 1 : 1 ;
m_apPlayers [ MAX_CLIENTS - i - 1 ] - > OnPredictedInput ( & Input ) ;
}
}
# endif
}
// Server hooks
void CGameContext : : OnClientDirectInput ( int ClientID , void * pInput )
{
if ( ! m_World . m_Paused )
m_apPlayers [ ClientID ] - > OnDirectInput ( ( CNetObj_PlayerInput * ) pInput ) ;
}
void CGameContext : : OnClientPredictedInput ( int ClientID , void * pInput )
{
if ( ! m_World . m_Paused )
m_apPlayers [ ClientID ] - > OnPredictedInput ( ( CNetObj_PlayerInput * ) pInput ) ;
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnClientEnter ( int ClientID )
2010-05-29 07:25:38 +00:00
{
//world.insert_entity(&players[client_id]);
2011-02-12 10:40:36 +00:00
m_apPlayers [ ClientID ] - > Respawn ( ) ;
2010-05-29 07:25:38 +00:00
char aBuf [ 512 ] ;
2011-02-12 10:40:36 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " '%s' entered and joined the %s " , Server ( ) - > ClientName ( ClientID ) , m_pController - > GetTeamName ( m_apPlayers [ ClientID ] - > GetTeam ( ) ) ) ;
2010-05-29 07:25:38 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , aBuf ) ;
2011-02-12 10:40:36 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " team_join player='%d:%s' team=%d " , ClientID , Server ( ) - > ClientName ( ClientID ) , m_apPlayers [ ClientID ] - > GetTeam ( ) ) ;
2010-08-17 22:06:00 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " game " , aBuf ) ;
2010-05-29 07:25:38 +00:00
m_VoteUpdate = true ;
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnClientConnected ( int ClientID )
2010-05-29 07:25:38 +00:00
{
// Check which team the player should be on
2011-02-12 10:40:36 +00:00
const int StartTeam = g_Config . m_SvTournamentMode ? TEAM_SPECTATORS : m_pController - > GetAutoTeam ( ClientID ) ;
2010-05-29 07:25:38 +00:00
2011-02-12 10:40:36 +00:00
m_apPlayers [ ClientID ] = new ( ClientID ) CPlayer ( this , ClientID , StartTeam ) ;
2010-05-29 07:25:38 +00:00
//players[client_id].init(client_id);
//players[client_id].client_id = client_id;
( void ) m_pController - > CheckTeamBalance ( ) ;
# ifdef CONF_DEBUG
if ( g_Config . m_DbgDummies )
{
2011-02-12 10:40:36 +00:00
if ( ClientID > = MAX_CLIENTS - g_Config . m_DbgDummies )
2010-05-29 07:25:38 +00:00
return ;
}
# endif
// send active vote
if ( m_VoteCloseTime )
2011-02-12 10:40:36 +00:00
SendVoteSet ( ClientID ) ;
2010-05-29 07:25:38 +00:00
// send motd
CNetMsg_Sv_Motd Msg ;
Msg . m_pMessage = g_Config . m_SvMotd ;
2011-02-12 10:40:36 +00:00
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnClientDrop ( int ClientID )
2010-05-29 07:25:38 +00:00
{
2011-02-12 10:40:36 +00:00
AbortVoteKickOnDisconnect ( ClientID ) ;
m_apPlayers [ ClientID ] - > OnDisconnect ( ) ;
delete m_apPlayers [ ClientID ] ;
m_apPlayers [ ClientID ] = 0 ;
2010-05-29 07:25:38 +00:00
( void ) m_pController - > CheckTeamBalance ( ) ;
m_VoteUpdate = true ;
2011-03-10 09:08:14 +00:00
// update spectator modes
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > m_SpectatorID = = ClientID )
m_apPlayers [ i ] - > m_SpectatorID = SPEC_FREEVIEW ;
}
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnMessage ( int MsgID , CUnpacker * pUnpacker , int ClientID )
2010-05-29 07:25:38 +00:00
{
2011-02-12 10:40:36 +00:00
void * pRawMsg = m_NetObjHandler . SecureUnpackMsg ( MsgID , pUnpacker ) ;
CPlayer * pPlayer = m_apPlayers [ ClientID ] ;
2010-05-29 07:25:38 +00:00
if ( ! pRawMsg )
{
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2011-02-12 10:40:36 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " dropped weird message '%s' (%d), failed on '%s' " , m_NetObjHandler . GetMsgName ( MsgID ) , MsgID , m_NetObjHandler . FailedMsgOn ( ) ) ;
2010-08-17 22:06:00 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
return ;
}
2011-02-12 10:40:36 +00:00
if ( MsgID = = NETMSGTYPE_CL_SAY )
2010-05-29 07:25:38 +00:00
{
CNetMsg_Cl_Say * pMsg = ( CNetMsg_Cl_Say * ) pRawMsg ;
int Team = pMsg - > m_Team ;
if ( Team )
2011-02-12 10:40:36 +00:00
Team = pPlayer - > GetTeam ( ) ;
2010-05-29 07:25:38 +00:00
else
Team = CGameContext : : CHAT_ALL ;
2011-03-10 09:08:14 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastChat & & pPlayer - > m_LastChat + Server ( ) - > TickSpeed ( ) > Server ( ) - > Tick ( ) )
2010-05-29 07:25:38 +00:00
return ;
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastChat = Server ( ) - > Tick ( ) ;
2010-05-29 07:25:38 +00:00
// check for invalid chars
unsigned char * pMessage = ( unsigned char * ) pMsg - > m_pMessage ;
while ( * pMessage )
{
if ( * pMessage < 32 )
* pMessage = ' ' ;
pMessage + + ;
}
2011-02-12 10:40:36 +00:00
SendChat ( ClientID , Team , pMsg - > m_pMessage ) ;
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
else if ( MsgID = = NETMSGTYPE_CL_CALLVOTE )
2010-05-29 07:25:38 +00:00
{
2011-03-10 09:08:14 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastVoteTry & & pPlayer - > m_LastVoteTry + Server ( ) - > TickSpeed ( ) * 3 > Server ( ) - > Tick ( ) )
2010-05-29 07:25:38 +00:00
return ;
int64 Now = Server ( ) - > Tick ( ) ;
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastVoteTry = Now ;
2011-02-12 10:40:36 +00:00
if ( pPlayer - > GetTeam ( ) = = TEAM_SPECTATORS )
2010-08-06 19:03:38 +00:00
{
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , " Spectators aren't allowed to start a vote. " ) ;
2010-08-06 19:03:38 +00:00
return ;
}
2010-05-29 07:25:38 +00:00
if ( m_VoteCloseTime )
{
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , " Wait for current vote to end before calling a new one. " ) ;
2010-05-29 07:25:38 +00:00
return ;
}
2008-09-24 14:47:03 +00:00
2011-03-10 09:08:14 +00:00
int Timeleft = pPlayer - > m_LastVoteCall + Server ( ) - > TickSpeed ( ) * 60 - Now ;
if ( pPlayer - > m_LastVoteCall & & Timeleft > 0 )
2010-05-29 07:25:38 +00:00
{
char aChatmsg [ 512 ] = { 0 } ;
str_format ( aChatmsg , sizeof ( aChatmsg ) , " You must wait %d seconds before making another vote " , ( Timeleft / Server ( ) - > TickSpeed ( ) ) + 1 ) ;
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , aChatmsg ) ;
2010-05-29 07:25:38 +00:00
return ;
}
char aChatmsg [ 512 ] = { 0 } ;
2011-03-25 09:26:59 +00:00
char aDesc [ 64 ] = { 0 } ;
2010-05-29 07:25:38 +00:00
char aCmd [ 512 ] = { 0 } ;
CNetMsg_Cl_CallVote * pMsg = ( CNetMsg_Cl_CallVote * ) pRawMsg ;
2011-03-25 09:26:59 +00:00
const char * pReason = pMsg - > m_Reason [ 0 ] ? pMsg - > m_Reason : " No reason given " ;
2010-05-29 07:25:38 +00:00
if ( str_comp_nocase ( pMsg - > m_Type , " option " ) = = 0 )
{
CVoteOption * pOption = m_pVoteOptionFirst ;
while ( pOption )
2008-10-21 17:26:32 +00:00
{
2011-03-25 08:49:21 +00:00
if ( str_comp_nocase ( pMsg - > m_Value , pOption - > m_aDescription ) = = 0 )
2010-05-29 07:25:38 +00:00
{
2011-03-25 09:26:59 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called vote to change server option '%s' (%s) " , Server ( ) - > ClientName ( ClientID ) ,
pOption - > m_aDescription , pReason ) ;
str_format ( aDesc , sizeof ( aDesc ) , " %s " , pOption - > m_aDescription ) ;
2010-05-29 07:25:38 +00:00
str_format ( aCmd , sizeof ( aCmd ) , " %s " , pOption - > m_aCommand ) ;
break ;
}
pOption = pOption - > m_pNext ;
}
2008-09-25 14:04:02 +00:00
2010-05-29 07:25:38 +00:00
if ( ! pOption )
{
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' isn't an option on this server " , pMsg - > m_Value ) ;
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , aChatmsg ) ;
2010-05-29 07:25:38 +00:00
return ;
2008-10-21 17:26:32 +00:00
}
2010-05-29 07:25:38 +00:00
}
else if ( str_comp_nocase ( pMsg - > m_Type , " kick " ) = = 0 )
{
if ( ! g_Config . m_SvVoteKick )
2008-10-21 17:26:32 +00:00
{
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , " Server does not allow voting to kick players " ) ;
2010-05-29 07:25:38 +00:00
return ;
2008-10-21 17:26:32 +00:00
}
2011-03-04 16:35:50 +00:00
if ( g_Config . m_SvVoteKickMin )
{
int PlayerNum = 0 ;
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > GetTeam ( ) ! = TEAM_SPECTATORS )
+ + PlayerNum ;
if ( PlayerNum < g_Config . m_SvVoteKickMin )
{
str_format ( aChatmsg , sizeof ( aChatmsg ) , " Kick voting requires %d players on the server " , g_Config . m_SvVoteKickMin ) ;
SendChatTarget ( ClientID , aChatmsg ) ;
return ;
}
}
2010-05-29 07:25:38 +00:00
2011-02-12 10:40:36 +00:00
int KickID = str_toint ( pMsg - > m_Value ) ;
if ( KickID < 0 | | KickID > = MAX_CLIENTS | | ! m_apPlayers [ KickID ] )
2010-05-29 07:25:38 +00:00
{
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , " Invalid client id to kick " ) ;
2010-05-29 07:25:38 +00:00
return ;
}
2011-02-12 10:40:36 +00:00
if ( KickID = = ClientID )
2010-06-02 02:42:17 +00:00
{
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , " You cant kick yourself " ) ;
2010-06-02 02:42:17 +00:00
return ;
}
2011-02-12 10:40:36 +00:00
if ( Server ( ) - > IsAuthed ( KickID ) )
2010-06-02 02:42:17 +00:00
{
2011-02-12 10:40:36 +00:00
SendChatTarget ( ClientID , " You cant kick admins " ) ;
2010-06-02 02:42:17 +00:00
char aBufKick [ 128 ] ;
2011-02-12 10:40:36 +00:00
str_format ( aBufKick , sizeof ( aBufKick ) , " '%s' called for vote to kick you " , Server ( ) - > ClientName ( ClientID ) ) ;
SendChatTarget ( KickID , aBufKick ) ;
2010-06-02 02:42:17 +00:00
return ;
}
2010-05-29 07:25:38 +00:00
2011-02-12 10:40:36 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called for vote to kick '%s' (%s) " , Server ( ) - > ClientName ( ClientID ) , Server ( ) - > ClientName ( KickID ) , pReason ) ;
str_format ( aDesc , sizeof ( aDesc ) , " Kick '%s' " , Server ( ) - > ClientName ( KickID ) ) ;
2010-05-29 07:25:38 +00:00
if ( ! g_Config . m_SvVoteKickBantime )
2011-02-12 10:40:36 +00:00
str_format ( aCmd , sizeof ( aCmd ) , " kick %d Kicked by vote " , KickID ) ;
2010-05-29 07:25:38 +00:00
else
{
char aBuf [ 64 ] = { 0 } ;
2011-02-12 10:40:36 +00:00
Server ( ) - > GetClientIP ( KickID , aBuf , sizeof ( aBuf ) ) ;
2010-10-13 18:31:21 +00:00
str_format ( aCmd , sizeof ( aCmd ) , " ban %s %d Banned by vote " , aBuf , g_Config . m_SvVoteKickBantime ) ;
2010-05-29 07:25:38 +00:00
}
}
if ( aCmd [ 0 ] )
{
SendChat ( - 1 , CGameContext : : CHAT_ALL , aChatmsg ) ;
2011-03-25 09:26:59 +00:00
StartVote ( aDesc , aCmd , pReason ) ;
2011-02-12 10:40:36 +00:00
pPlayer - > m_Vote = 1 ;
pPlayer - > m_VotePos = m_VotePos = 1 ;
m_VoteCreator = ClientID ;
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastVoteCall = Now ;
2010-05-29 07:25:38 +00:00
}
}
2011-02-12 10:40:36 +00:00
else if ( MsgID = = NETMSGTYPE_CL_VOTE )
2010-05-29 07:25:38 +00:00
{
if ( ! m_VoteCloseTime )
return ;
2011-02-12 10:40:36 +00:00
if ( pPlayer - > m_Vote = = 0 )
2010-05-29 07:25:38 +00:00
{
CNetMsg_Cl_Vote * pMsg = ( CNetMsg_Cl_Vote * ) pRawMsg ;
if ( ! pMsg - > m_Vote )
return ;
2011-02-12 10:40:36 +00:00
pPlayer - > m_Vote = pMsg - > m_Vote ;
pPlayer - > m_VotePos = + + m_VotePos ;
2010-05-29 07:25:38 +00:00
m_VoteUpdate = true ;
2008-09-25 12:23:44 +00:00
}
2008-09-24 14:47:03 +00:00
}
2011-02-12 10:40:36 +00:00
else if ( MsgID = = NETMSGTYPE_CL_SETTEAM & & ! m_World . m_Paused )
2010-05-29 07:25:38 +00:00
{
CNetMsg_Cl_SetTeam * pMsg = ( CNetMsg_Cl_SetTeam * ) pRawMsg ;
2011-03-10 09:08:14 +00:00
if ( pPlayer - > GetTeam ( ) = = pMsg - > m_Team | | ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastSetTeam & & pPlayer - > m_LastSetTeam + Server ( ) - > TickSpeed ( ) * 3 > Server ( ) - > Tick ( ) ) )
2010-05-29 07:25:38 +00:00
return ;
// Switch team on given client and kill/respawn him
2011-02-12 10:40:36 +00:00
if ( m_pController - > CanJoinTeam ( pMsg - > m_Team , ClientID ) )
2010-05-29 07:25:38 +00:00
{
2011-02-12 10:40:36 +00:00
if ( m_pController - > CanChangeTeam ( pPlayer , pMsg - > m_Team ) )
2010-05-29 07:25:38 +00:00
{
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastSetTeam = Server ( ) - > Tick ( ) ;
2011-02-12 10:40:36 +00:00
if ( pPlayer - > GetTeam ( ) = = TEAM_SPECTATORS | | pMsg - > m_Team = = TEAM_SPECTATORS )
2010-05-29 07:25:38 +00:00
m_VoteUpdate = true ;
2011-02-12 10:40:36 +00:00
pPlayer - > SetTeam ( pMsg - > m_Team ) ;
2010-05-29 07:25:38 +00:00
( void ) m_pController - > CheckTeamBalance ( ) ;
}
else
2011-02-12 10:40:36 +00:00
SendBroadcast ( " Teams must be balanced, please join other team " , ClientID ) ;
2010-05-29 07:25:38 +00:00
}
else
{
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " Only %d active players are allowed " , g_Config . m_SvMaxClients - g_Config . m_SvSpectatorSlots ) ;
2011-02-12 10:40:36 +00:00
SendBroadcast ( aBuf , ClientID ) ;
2010-05-29 07:25:38 +00:00
}
}
2011-03-10 09:08:14 +00:00
else if ( MsgID = = NETMSGTYPE_CL_SETSPECTATORMODE & & ! m_World . m_Paused )
{
CNetMsg_Cl_SetSpectatorMode * pMsg = ( CNetMsg_Cl_SetSpectatorMode * ) pRawMsg ;
if ( pPlayer - > GetTeam ( ) ! = TEAM_SPECTATORS | | pPlayer - > m_SpectatorID = = pMsg - > m_SpectatorID | | ClientID = = pMsg - > m_SpectatorID | |
( g_Config . m_SvSpamprotection & & pPlayer - > m_LastSetSpectatorMode & & pPlayer - > m_LastSetSpectatorMode + Server ( ) - > TickSpeed ( ) * 3 > Server ( ) - > Tick ( ) ) )
return ;
pPlayer - > m_LastSetSpectatorMode = Server ( ) - > Tick ( ) ;
if ( pMsg - > m_SpectatorID ! = SPEC_FREEVIEW & & ! m_apPlayers [ pMsg - > m_SpectatorID ] )
SendChatTarget ( ClientID , " Invalid spectator id used " ) ;
else
pPlayer - > m_SpectatorID = pMsg - > m_SpectatorID ;
}
2011-03-15 08:58:57 +00:00
else if ( MsgID = = NETMSGTYPE_CL_STARTINFO )
{
if ( pPlayer - > m_IsReady )
2010-05-29 07:25:38 +00:00
return ;
2011-03-15 08:58:57 +00:00
CNetMsg_Cl_StartInfo * pMsg = ( CNetMsg_Cl_StartInfo * ) pRawMsg ;
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastChangeInfo = Server ( ) - > Tick ( ) ;
2010-05-29 07:25:38 +00:00
2011-03-15 08:58:57 +00:00
// set start infos
Server ( ) - > SetClientName ( ClientID , pMsg - > m_pName ) ;
2011-03-15 10:23:49 +00:00
Server ( ) - > SetClientClan ( ClientID , pMsg - > m_pClan ) ;
Server ( ) - > SetClientCountry ( ClientID , pMsg - > m_Country ) ;
2011-03-15 08:58:57 +00:00
str_copy ( pPlayer - > m_TeeInfos . m_SkinName , pMsg - > m_pSkin , sizeof ( pPlayer - > m_TeeInfos . m_SkinName ) ) ;
2011-02-12 10:40:36 +00:00
pPlayer - > m_TeeInfos . m_UseCustomColor = pMsg - > m_UseCustomColor ;
pPlayer - > m_TeeInfos . m_ColorBody = pMsg - > m_ColorBody ;
pPlayer - > m_TeeInfos . m_ColorFeet = pMsg - > m_ColorFeet ;
2011-03-15 08:58:57 +00:00
m_pController - > OnPlayerInfoChange ( pPlayer ) ;
2010-05-29 07:25:38 +00:00
2011-03-15 08:58:57 +00:00
// send vote options
CNetMsg_Sv_VoteClearOptions ClearMsg ;
Server ( ) - > SendPackMsg ( & ClearMsg , MSGFLAG_VITAL , ClientID ) ;
CVoteOption * pCurrent = m_pVoteOptionFirst ;
while ( pCurrent )
{
2011-03-25 10:49:35 +00:00
CNetMsg_Sv_VoteOptionAdd OptionMsg ;
2011-03-25 08:49:21 +00:00
OptionMsg . m_pDescription = pCurrent - > m_aDescription ;
2011-03-15 08:58:57 +00:00
Server ( ) - > SendPackMsg ( & OptionMsg , MSGFLAG_VITAL , ClientID ) ;
pCurrent = pCurrent - > m_pNext ;
}
// send tuning parameters to client
SendTuningParams ( ClientID ) ;
// client is ready to enter
pPlayer - > m_IsReady = true ;
CNetMsg_Sv_ReadyToEnter m ;
Server ( ) - > SendPackMsg ( & m , MSGFLAG_VITAL | MSGFLAG_FLUSH , ClientID ) ;
}
else if ( MsgID = = NETMSGTYPE_CL_CHANGEINFO )
{
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastChangeInfo & & pPlayer - > m_LastChangeInfo + Server ( ) - > TickSpeed ( ) * 5 > Server ( ) - > Tick ( ) )
return ;
CNetMsg_Cl_ChangeInfo * pMsg = ( CNetMsg_Cl_ChangeInfo * ) pRawMsg ;
pPlayer - > m_LastChangeInfo = Server ( ) - > Tick ( ) ;
2010-05-29 07:25:38 +00:00
2011-03-15 08:58:57 +00:00
// set infos
char aOldName [ MAX_NAME_LENGTH ] ;
str_copy ( aOldName , Server ( ) - > ClientName ( ClientID ) , sizeof ( aOldName ) ) ;
2011-02-12 10:40:36 +00:00
Server ( ) - > SetClientName ( ClientID , pMsg - > m_pName ) ;
2011-03-15 08:58:57 +00:00
if ( str_comp ( aOldName , Server ( ) - > ClientName ( ClientID ) ) ! = 0 )
2010-05-29 07:25:38 +00:00
{
char aChatText [ 256 ] ;
2011-02-12 10:40:36 +00:00
str_format ( aChatText , sizeof ( aChatText ) , " '%s' changed name to '%s' " , aOldName , Server ( ) - > ClientName ( ClientID ) ) ;
2010-05-29 07:25:38 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , aChatText ) ;
}
2011-03-15 10:23:49 +00:00
Server ( ) - > SetClientClan ( ClientID , pMsg - > m_pClan ) ;
Server ( ) - > SetClientCountry ( ClientID , pMsg - > m_Country ) ;
2011-02-12 10:40:36 +00:00
str_copy ( pPlayer - > m_TeeInfos . m_SkinName , pMsg - > m_pSkin , sizeof ( pPlayer - > m_TeeInfos . m_SkinName ) ) ;
2011-03-15 08:58:57 +00:00
pPlayer - > m_TeeInfos . m_UseCustomColor = pMsg - > m_UseCustomColor ;
pPlayer - > m_TeeInfos . m_ColorBody = pMsg - > m_ColorBody ;
pPlayer - > m_TeeInfos . m_ColorFeet = pMsg - > m_ColorFeet ;
2011-02-12 10:40:36 +00:00
m_pController - > OnPlayerInfoChange ( pPlayer ) ;
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
else if ( MsgID = = NETMSGTYPE_CL_EMOTICON & & ! m_World . m_Paused )
2010-05-29 07:25:38 +00:00
{
CNetMsg_Cl_Emoticon * pMsg = ( CNetMsg_Cl_Emoticon * ) pRawMsg ;
2011-03-10 09:08:14 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastEmote & & pPlayer - > m_LastEmote + Server ( ) - > TickSpeed ( ) * 3 > Server ( ) - > Tick ( ) )
2010-05-29 07:25:38 +00:00
return ;
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastEmote = Server ( ) - > Tick ( ) ;
2010-05-29 07:25:38 +00:00
2011-02-12 10:40:36 +00:00
SendEmoticon ( ClientID , pMsg - > m_Emoticon ) ;
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
else if ( MsgID = = NETMSGTYPE_CL_KILL & & ! m_World . m_Paused )
2010-05-29 07:25:38 +00:00
{
2011-03-10 09:08:14 +00:00
if ( pPlayer - > m_LastKill & & pPlayer - > m_LastKill + Server ( ) - > TickSpeed ( ) * 3 > Server ( ) - > Tick ( ) )
2010-05-29 07:25:38 +00:00
return ;
2011-03-10 09:08:14 +00:00
pPlayer - > m_LastKill = Server ( ) - > Tick ( ) ;
2011-02-12 10:40:36 +00:00
pPlayer - > KillCharacter ( WEAPON_SELF ) ;
pPlayer - > m_RespawnTick = Server ( ) - > Tick ( ) + Server ( ) - > TickSpeed ( ) * 3 ;
2010-05-29 07:25:38 +00:00
}
}
void CGameContext : : ConTuneParam ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
const char * pParamName = pResult - > GetString ( 0 ) ;
float NewValue = pResult - > GetFloat ( 1 ) ;
if ( pSelf - > Tuning ( ) - > Set ( pParamName , NewValue ) )
{
2010-09-12 11:06:43 +00:00
char aBuf [ 256 ] ;
2010-08-17 22:06:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %s changed to %.2f " , pParamName , NewValue ) ;
2010-09-12 11:06:43 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
2010-05-29 07:25:38 +00:00
pSelf - > SendTuningParams ( - 1 ) ;
}
else
2010-09-12 11:06:43 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " No such tuning parameter " ) ;
2010-05-29 07:25:38 +00:00
}
void CGameContext : : ConTuneReset ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-02-12 10:40:36 +00:00
CTuningParams TuningParams ;
* pSelf - > Tuning ( ) = TuningParams ;
2010-05-29 07:25:38 +00:00
pSelf - > SendTuningParams ( - 1 ) ;
2010-08-17 22:06:00 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " Tuning reset " ) ;
2010-05-29 07:25:38 +00:00
}
void CGameContext : : ConTuneDump ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < pSelf - > Tuning ( ) - > Num ( ) ; i + + )
{
2011-02-13 06:47:51 +00:00
float v ;
pSelf - > Tuning ( ) - > Get ( i , & v ) ;
str_format ( aBuf , sizeof ( aBuf ) , " %s %.2f " , pSelf - > Tuning ( ) - > m_apNames [ i ] , v ) ;
2010-08-17 22:06:00 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
}
void CGameContext : : ConChangeMap ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2010-11-17 11:50:01 +00:00
pSelf - > m_pController - > ChangeMap ( pResult - > NumArguments ( ) ? pResult - > GetString ( 0 ) : " " ) ;
2010-05-29 07:25:38 +00:00
}
void CGameContext : : ConRestart ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
if ( pResult - > NumArguments ( ) )
pSelf - > m_pController - > DoWarmup ( pResult - > GetInteger ( 0 ) ) ;
else
pSelf - > m_pController - > StartRound ( ) ;
}
void CGameContext : : ConBroadcast ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
pSelf - > SendBroadcast ( pResult - > GetString ( 0 ) , - 1 ) ;
}
void CGameContext : : ConSay ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
pSelf - > SendChat ( - 1 , CGameContext : : CHAT_ALL , pResult - > GetString ( 0 ) ) ;
}
void CGameContext : : ConSetTeam ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-02-12 10:40:36 +00:00
int ClientID = clamp ( pResult - > GetInteger ( 0 ) , 0 , ( int ) MAX_CLIENTS - 1 ) ;
2010-05-29 07:25:38 +00:00
int Team = clamp ( pResult - > GetInteger ( 1 ) , - 1 , 1 ) ;
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2011-02-12 10:40:36 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " moved client %d to team %d " , ClientID , Team ) ;
2010-08-17 22:06:00 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
2011-02-12 10:40:36 +00:00
if ( ! pSelf - > m_apPlayers [ ClientID ] )
2010-05-29 07:25:38 +00:00
return ;
2011-02-12 10:40:36 +00:00
pSelf - > m_apPlayers [ ClientID ] - > SetTeam ( Team ) ;
2010-05-29 07:25:38 +00:00
( void ) pSelf - > m_pController - > CheckTeamBalance ( ) ;
}
2011-01-06 12:37:28 +00:00
void CGameContext : : ConSetTeamAll ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
int Team = clamp ( pResult - > GetInteger ( 0 ) , - 1 , 1 ) ;
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " moved all clients to team %d " , Team ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
if ( pSelf - > m_apPlayers [ i ] )
pSelf - > m_apPlayers [ i ] - > SetTeam ( Team ) ;
( void ) pSelf - > m_pController - > CheckTeamBalance ( ) ;
}
2010-05-29 07:25:38 +00:00
void CGameContext : : ConAddVote ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-03-25 08:49:21 +00:00
const char * pDescription = pResult - > GetString ( 0 ) ;
const char * pCommand = pResult - > GetString ( 1 ) ;
2010-11-20 18:30:52 +00:00
2010-10-25 16:30:35 +00:00
// check for valid option
2011-03-25 08:49:21 +00:00
if ( ! pSelf - > Console ( ) - > LineIsValid ( pCommand ) )
2010-10-25 16:30:35 +00:00
{
char aBuf [ 256 ] ;
2011-03-25 08:49:21 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " skipped invalid option '%s' " , pCommand ) ;
2010-10-25 16:30:35 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
return ;
}
2010-05-29 07:25:38 +00:00
2011-03-25 08:49:21 +00:00
// check for duplicate entry
2010-11-20 18:30:52 +00:00
CGameContext : : CVoteOption * pOption = pSelf - > m_pVoteOptionFirst ;
while ( pOption )
{
2011-03-25 10:49:35 +00:00
if ( str_comp_nocase ( pDescription , pOption - > m_aDescription ) = = 0 )
2010-11-20 18:30:52 +00:00
{
char aBuf [ 256 ] ;
2011-03-25 08:49:21 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " option '%s' already exists " , pDescription ) ;
2010-11-20 18:30:52 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
return ;
}
pOption = pOption - > m_pNext ;
}
2011-03-25 08:49:21 +00:00
// add the option
int Len = str_length ( pCommand ) ;
2010-11-20 18:30:52 +00:00
pOption = ( CGameContext : : CVoteOption * ) pSelf - > m_pVoteOptionHeap - > Allocate ( sizeof ( CGameContext : : CVoteOption ) + Len ) ;
2010-05-29 07:25:38 +00:00
pOption - > m_pNext = 0 ;
pOption - > m_pPrev = pSelf - > m_pVoteOptionLast ;
if ( pOption - > m_pPrev )
pOption - > m_pPrev - > m_pNext = pOption ;
pSelf - > m_pVoteOptionLast = pOption ;
if ( ! pSelf - > m_pVoteOptionFirst )
pSelf - > m_pVoteOptionFirst = pOption ;
2011-03-25 08:49:21 +00:00
str_copy ( pOption - > m_aDescription , pDescription , sizeof ( pOption - > m_aDescription ) ) ;
mem_copy ( pOption - > m_aCommand , pCommand , Len + 1 ) ;
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2011-03-25 08:49:21 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " added option '%s' '%s' " , pOption - > m_aDescription , pOption - > m_aCommand ) ;
2010-08-17 22:06:00 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
2011-03-25 10:49:35 +00:00
// inform clients about added option
CNetMsg_Sv_VoteOptionAdd OptionMsg ;
OptionMsg . m_pDescription = pOption - > m_aDescription ;
pSelf - > Server ( ) - > SendPackMsg ( & OptionMsg , MSGFLAG_VITAL , - 1 ) ;
}
void CGameContext : : ConRemoveVote ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
const char * pDescription = pResult - > GetString ( 0 ) ;
// check for valid option
CGameContext : : CVoteOption * pOption = pSelf - > m_pVoteOptionFirst ;
while ( pOption )
{
if ( str_comp_nocase ( pDescription , pOption - > m_aDescription ) = = 0 )
break ;
pOption = pOption - > m_pNext ;
}
if ( ! pOption )
{
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " option '%s' does not exist " , pDescription ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
return ;
}
// TODO: improve this
// remove the option
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " removed option '%s' '%s' " , pOption - > m_aDescription , pOption - > m_aCommand ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2011-03-25 11:06:45 +00:00
CHeap * pVoteOptionHeap = new CHeap ( ) ;
2011-03-25 10:49:35 +00:00
CVoteOption * pVoteOptionFirst = 0 ;
2011-03-25 11:06:45 +00:00
CVoteOption * pVoteOptionLast = 0 ;
2011-03-25 10:49:35 +00:00
for ( CVoteOption * pSrc = pSelf - > m_pVoteOptionFirst ; pSrc ; pSrc = pSrc - > m_pNext )
{
if ( pSrc = = pOption )
continue ;
// copy option
int Len = str_length ( pSrc - > m_aCommand ) ;
CVoteOption * pDst = ( CGameContext : : CVoteOption * ) pVoteOptionHeap - > Allocate ( sizeof ( CGameContext : : CVoteOption ) + Len ) ;
pDst - > m_pNext = 0 ;
pDst - > m_pPrev = pVoteOptionLast ;
if ( pDst - > m_pPrev )
pDst - > m_pPrev - > m_pNext = pDst ;
pVoteOptionLast = pDst ;
if ( ! pVoteOptionFirst )
pVoteOptionFirst = pDst ;
str_copy ( pDst - > m_aDescription , pSrc - > m_aDescription , sizeof ( pDst - > m_aDescription ) ) ;
mem_copy ( pDst - > m_aCommand , pSrc - > m_aCommand , Len + 1 ) ;
2011-03-25 11:06:45 +00:00
}
// clean up
delete pSelf - > m_pVoteOptionHeap ;
2011-03-25 10:49:35 +00:00
pSelf - > m_pVoteOptionHeap = pVoteOptionHeap ;
pSelf - > m_pVoteOptionFirst = pVoteOptionFirst ;
pSelf - > m_pVoteOptionLast = pVoteOptionLast ;
// inform clients about removed option
CNetMsg_Sv_VoteOptionRemove OptionMsg ;
2011-03-25 08:49:21 +00:00
OptionMsg . m_pDescription = pOption - > m_aDescription ;
2010-05-29 07:25:38 +00:00
pSelf - > Server ( ) - > SendPackMsg ( & OptionMsg , MSGFLAG_VITAL , - 1 ) ;
}
2011-03-25 11:06:45 +00:00
void CGameContext : : ConForceVote ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
const char * pType = pResult - > GetString ( 0 ) ;
const char * pValue = pResult - > GetString ( 1 ) ;
2011-03-26 15:24:12 +00:00
const char * pReason = pResult - > NumArguments ( ) > 2 & & pResult - > GetString ( 2 ) [ 0 ] ? pResult - > GetString ( 2 ) : " No reason given " ;
2011-03-25 11:06:45 +00:00
char aBuf [ 128 ] = { 0 } ;
if ( str_comp_nocase ( pType , " option " ) = = 0 )
{
CVoteOption * pOption = pSelf - > m_pVoteOptionFirst ;
while ( pOption )
{
if ( str_comp_nocase ( pValue , pOption - > m_aDescription ) = = 0 )
{
str_format ( aBuf , sizeof ( aBuf ) , " admin forced server option '%s' (%s) " , pValue , pReason ) ;
pSelf - > SendChatTarget ( - 1 , aBuf ) ;
pSelf - > Console ( ) - > ExecuteLine ( pOption - > m_aCommand ) ;
break ;
}
pOption = pOption - > m_pNext ;
}
if ( ! pOption )
{
str_format ( aBuf , sizeof ( aBuf ) , " '%s' isn't an option on this server " , pValue ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
return ;
}
}
else if ( str_comp_nocase ( pType , " kick " ) = = 0 )
{
int KickID = str_toint ( pValue ) ;
if ( KickID < 0 | | KickID > = MAX_CLIENTS | | ! pSelf - > m_apPlayers [ KickID ] )
{
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " Invalid client id to kick " ) ;
return ;
}
if ( ! g_Config . m_SvVoteKickBantime )
{
str_format ( aBuf , sizeof ( aBuf ) , " kick %d %s " , KickID , pReason ) ;
pSelf - > Console ( ) - > ExecuteLine ( aBuf ) ;
}
else
{
char aIP [ 64 ] = { 0 } ;
pSelf - > Server ( ) - > GetClientIP ( KickID , aIP , sizeof ( aIP ) ) ;
str_format ( aBuf , sizeof ( aBuf ) , " ban %s %d %s " , aIP , g_Config . m_SvVoteKickBantime , pReason ) ;
pSelf - > Console ( ) - > ExecuteLine ( aBuf ) ;
}
}
}
2011-01-21 19:46:00 +00:00
void CGameContext : : ConClearVotes ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " cleared votes " ) ;
CNetMsg_Sv_VoteClearOptions VoteClearOptionsMsg ;
pSelf - > Server ( ) - > SendPackMsg ( & VoteClearOptionsMsg , MSGFLAG_VITAL , - 1 ) ;
pSelf - > m_pVoteOptionHeap - > Reset ( ) ;
pSelf - > m_pVoteOptionFirst = 0 ;
pSelf - > m_pVoteOptionLast = 0 ;
}
2010-05-29 07:25:38 +00:00
void CGameContext : : ConVote ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
if ( str_comp_nocase ( pResult - > GetString ( 0 ) , " yes " ) = = 0 )
pSelf - > m_VoteEnforce = CGameContext : : VOTE_ENFORCE_YES ;
else if ( str_comp_nocase ( pResult - > GetString ( 0 ) , " no " ) = = 0 )
pSelf - > m_VoteEnforce = CGameContext : : VOTE_ENFORCE_NO ;
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " forcing vote %s " , pResult - > GetString ( 0 ) ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
void CGameContext : : ConchainSpecialMotdupdate ( IConsole : : IResult * pResult , void * pUserData , IConsole : : FCommandCallback pfnCallback , void * pCallbackUserData )
{
pfnCallback ( pResult , pCallbackUserData ) ;
if ( pResult - > NumArguments ( ) )
{
CNetMsg_Sv_Motd Msg ;
Msg . m_pMessage = g_Config . m_SvMotd ;
CGameContext * pSelf = ( CGameContext * ) pUserData ;
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
if ( pSelf - > m_apPlayers [ i ] )
pSelf - > Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , i ) ;
}
}
void CGameContext : : OnConsoleInit ( )
{
m_pServer = Kernel ( ) - > RequestInterface < IServer > ( ) ;
m_pConsole = Kernel ( ) - > RequestInterface < IConsole > ( ) ;
Console ( ) - > Register ( " tune " , " si " , CFGFLAG_SERVER , ConTuneParam , this , " " ) ;
Console ( ) - > Register ( " tune_reset " , " " , CFGFLAG_SERVER , ConTuneReset , this , " " ) ;
Console ( ) - > Register ( " tune_dump " , " " , CFGFLAG_SERVER , ConTuneDump , this , " " ) ;
2010-11-17 11:50:01 +00:00
Console ( ) - > Register ( " change_map " , " ?r " , CFGFLAG_SERVER | CFGFLAG_STORE , ConChangeMap , this , " " ) ;
2010-08-07 18:22:25 +00:00
Console ( ) - > Register ( " restart " , " ?i " , CFGFLAG_SERVER | CFGFLAG_STORE , ConRestart , this , " " ) ;
2010-05-29 07:25:38 +00:00
Console ( ) - > Register ( " broadcast " , " r " , CFGFLAG_SERVER , ConBroadcast , this , " " ) ;
Console ( ) - > Register ( " say " , " r " , CFGFLAG_SERVER , ConSay , this , " " ) ;
Console ( ) - > Register ( " set_team " , " ii " , CFGFLAG_SERVER , ConSetTeam , this , " " ) ;
2011-01-06 12:37:28 +00:00
Console ( ) - > Register ( " set_team_all " , " i " , CFGFLAG_SERVER , ConSetTeamAll , this , " " ) ;
2010-05-29 07:25:38 +00:00
2011-03-25 08:49:21 +00:00
Console ( ) - > Register ( " add_vote " , " sr " , CFGFLAG_SERVER , ConAddVote , this , " " ) ;
2011-03-25 10:49:35 +00:00
Console ( ) - > Register ( " remove_vote " , " s " , CFGFLAG_SERVER , ConRemoveVote , this , " " ) ;
2011-03-25 11:06:45 +00:00
Console ( ) - > Register ( " force_vote " , " ss?r " , CFGFLAG_SERVER , ConForceVote , this , " " ) ;
2011-01-21 19:46:00 +00:00
Console ( ) - > Register ( " clear_votes " , " " , CFGFLAG_SERVER , ConClearVotes , this , " " ) ;
2010-05-29 07:25:38 +00:00
Console ( ) - > Register ( " vote " , " r " , CFGFLAG_SERVER , ConVote , this , " " ) ;
Console ( ) - > Chain ( " sv_motd " , ConchainSpecialMotdupdate , this ) ;
}
void CGameContext : : OnInit ( /*class IKernel *pKernel*/ )
{
m_pServer = Kernel ( ) - > RequestInterface < IServer > ( ) ;
m_pConsole = Kernel ( ) - > RequestInterface < IConsole > ( ) ;
m_World . SetGameServer ( this ) ;
m_Events . SetGameServer ( this ) ;
//if(!data) // only load once
//data = load_data_from_memory(internal_data);
for ( int i = 0 ; i < NUM_NETOBJTYPES ; i + + )
Server ( ) - > SnapSetStaticsize ( i , m_NetObjHandler . GetObjSize ( i ) ) ;
m_Layers . Init ( Kernel ( ) ) ;
m_Collision . Init ( & m_Layers ) ;
// reset everything here
//world = new GAMEWORLD;
//players = new CPlayer[MAX_CLIENTS];
// select gametype
if ( str_comp ( g_Config . m_SvGametype , " mod " ) = = 0 )
m_pController = new CGameControllerMOD ( this ) ;
else if ( str_comp ( g_Config . m_SvGametype , " ctf " ) = = 0 )
m_pController = new CGameControllerCTF ( this ) ;
else if ( str_comp ( g_Config . m_SvGametype , " tdm " ) = = 0 )
m_pController = new CGameControllerTDM ( this ) ;
else
m_pController = new CGameControllerDM ( this ) ;
// setup core world
//for(int i = 0; i < MAX_CLIENTS; i++)
// game.players[i].core.world = &game.world.core;
// create all entities from the game layer
CMapItemLayerTilemap * pTileMap = m_Layers . GameLayer ( ) ;
CTile * pTiles = ( CTile * ) Kernel ( ) - > RequestInterface < IMap > ( ) - > GetData ( pTileMap - > m_Data ) ;
/*
num_spawn_points [ 0 ] = 0 ;
num_spawn_points [ 1 ] = 0 ;
num_spawn_points [ 2 ] = 0 ;
*/
for ( int y = 0 ; y < pTileMap - > m_Height ; y + + )
{
for ( int x = 0 ; x < pTileMap - > m_Width ; x + + )
{
int Index = pTiles [ y * pTileMap - > m_Width + x ] . m_Index ;
if ( Index > = ENTITY_OFFSET )
{
vec2 Pos ( x * 32.0f + 16.0f , y * 32.0f + 16.0f ) ;
m_pController - > OnEntity ( Index - ENTITY_OFFSET , Pos ) ;
}
}
}
//game.world.insert_entity(game.Controller);
# ifdef CONF_DEBUG
if ( g_Config . m_DbgDummies )
{
for ( int i = 0 ; i < g_Config . m_DbgDummies ; i + + )
{
OnClientConnected ( MAX_CLIENTS - i - 1 ) ;
}
}
# endif
}
void CGameContext : : OnShutdown ( )
{
delete m_pController ;
m_pController = 0 ;
Clear ( ) ;
2008-08-14 18:42:47 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnSnap ( int ClientID )
2008-08-14 18:42:47 +00:00
{
2011-02-12 10:40:36 +00:00
m_World . Snap ( ClientID ) ;
m_pController - > Snap ( ClientID ) ;
m_Events . Snap ( ClientID ) ;
2008-08-14 18:42:47 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
2010-05-29 07:25:38 +00:00
if ( m_apPlayers [ i ] )
2011-02-12 10:40:36 +00:00
m_apPlayers [ i ] - > Snap ( ClientID ) ;
2008-08-14 18:42:47 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CGameContext : : OnPreSnap ( ) { }
void CGameContext : : OnPostSnap ( )
{
m_Events . Clear ( ) ;
}
2011-03-15 08:58:57 +00:00
bool CGameContext : : IsClientReady ( int ClientID )
{
return m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > m_IsReady ? true : false ;
}
2011-03-20 14:33:49 +00:00
bool CGameContext : : IsClientPlayer ( int ClientID )
{
return m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > GetTeam ( ) = = TEAM_SPECTATORS ? false : true ;
}
2011-02-16 11:31:47 +00:00
const char * CGameContext : : GameType ( ) { return m_pController & & m_pController - > m_pGameType ? m_pController - > m_pGameType : " " ; }
2010-05-29 07:25:38 +00:00
const char * CGameContext : : Version ( ) { return GAME_VERSION ; }
const char * CGameContext : : NetVersion ( ) { return GAME_NETVERSION ; }
2011-02-13 12:06:19 +00:00
IGameServer * CreateGameServer ( ) { return new CGameContext ; }