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. */
2011-08-31 11:56:04 +00:00
# include <base/tl/sorted_array.h>
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>
2015-07-14 20:08:29 +00:00
# include <engine/shared/datafile.h>
# include <engine/shared/linereader.h>
# include <engine/storage.h>
2010-05-29 07:25:38 +00:00
# include "gamecontext.h"
# include <game/version.h>
# include <game/collision.h>
2014-03-12 23:31:50 +00:00
# include <game/gamecore.h>
/*#include "gamemodes/dm.h"
2011-01-29 00:59:50 +00:00
# include "gamemodes/tdm.h"
# include "gamemodes/ctf.h"
2011-04-09 06:41:31 +00:00
# include "gamemodes/mod.h" * /
2008-08-14 18:42:47 +00:00
2011-04-09 06:41:31 +00:00
# include "gamemodes/DDRace.h"
2010-08-23 19:37:27 +00:00
# include "score.h"
# include "score/file_score.h"
2010-11-16 13:44:16 +00:00
# if defined(CONF_SQL)
2010-08-26 13:27:36 +00:00
# include "score/sql_score.h"
2010-11-16 13:25:21 +00:00
# endif
2010-08-23 19:37:27 +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 ;
2011-04-13 18:37:12 +00:00
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 ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
m_pController = 0 ;
m_VoteCloseTime = 0 ;
m_pVoteOptionFirst = 0 ;
m_pVoteOptionLast = 0 ;
2011-03-26 21:06:29 +00:00
m_NumVoteOptions = 0 ;
2014-03-04 01:48:58 +00:00
m_LastMapVote = 0 ;
2012-04-12 00:09:31 +00:00
//m_LockTeams = 0;
2010-05-29 07:25:38 +00:00
if ( Resetting = = NO_RESET )
2011-02-03 12:02:32 +00:00
{
2010-05-29 07:25:38 +00:00
m_pVoteOptionHeap = new CHeap ( ) ;
2011-02-23 21:39:53 +00:00
m_pScore = 0 ;
m_NumMutes = 0 ;
2011-02-03 12:02:32 +00:00
}
2011-08-31 13:41:32 +00:00
m_ChatResponseTargetID = - 1 ;
2015-07-14 20:08:29 +00:00
m_aDeleteTempfile [ 0 ] = 0 ;
2017-09-12 12:58:44 +00:00
m_TeeHistorianActive = false ;
2010-05-29 07:25:38 +00:00
}
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 ;
2013-08-03 15:22:50 +00:00
if ( m_pScore )
delete m_pScore ;
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 ;
2011-03-26 16:44:34 +00:00
CVoteOptionServer * pVoteOptionFirst = m_pVoteOptionFirst ;
CVoteOptionServer * pVoteOptionLast = m_pVoteOptionLast ;
2011-03-26 21:06:29 +00:00
int NumVoteOptions = m_NumVoteOptions ;
2010-05-29 07:25:38 +00:00
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 ;
2011-03-26 21:06:29 +00:00
m_NumVoteOptions = NumVoteOptions ;
2010-05-29 07:25:38 +00:00
m_Tuning = Tuning ;
2008-08-14 18:42:47 +00:00
}
2017-09-12 12:58:44 +00:00
void CGameContext : : TeeHistorianWrite ( const void * pData , int DataSize , void * pUser )
{
CGameContext * pSelf = ( CGameContext * ) pUser ;
2017-10-13 00:48:42 +00:00
aio_write ( pSelf - > m_pTeeHistorianFile , pData , DataSize ) ;
2017-09-12 12:58:44 +00:00
}
2017-09-13 20:35:09 +00:00
void CGameContext : : CommandCallback ( int ClientID , int FlagMask , const char * pCmd , IConsole : : IResult * pResult , void * pUser )
{
CGameContext * pSelf = ( CGameContext * ) pUser ;
if ( pSelf - > m_TeeHistorianActive )
{
pSelf - > m_TeeHistorian . RecordConsoleCommand ( ClientID , FlagMask , pCmd , pResult ) ;
}
}
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
}
2013-12-31 05:13:57 +00:00
void CGameContext : : CreateDamageInd ( vec2 Pos , float Angle , int Amount , int64_t Mask )
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-06-02 17:13:40 +00:00
CNetEvent_DamageInd * pEvent = ( CNetEvent_DamageInd * ) m_Events . Create ( NETEVENTTYPE_DAMAGEIND , sizeof ( CNetEvent_DamageInd ) , Mask ) ;
2011-02-12 10:40:36 +00:00
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
}
}
}
2013-12-31 05:13:57 +00:00
void CGameContext : : CreateHammerHit ( vec2 Pos , int64_t Mask )
2008-10-17 11:23:21 +00:00
{
// create the event
2011-06-02 17:13:40 +00:00
CNetEvent_HammerHit * pEvent = ( CNetEvent_HammerHit * ) m_Events . Create ( NETEVENTTYPE_HAMMERHIT , sizeof ( CNetEvent_HammerHit ) , Mask ) ;
2011-02-12 10:40:36 +00:00
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
}
}
2013-12-31 05:13:57 +00:00
void CGameContext : : CreateExplosion ( vec2 Pos , int Owner , int Weapon , bool NoDamage , int ActivatedTeam , int64_t Mask )
2008-08-14 18:42:47 +00:00
{
// create the event
2011-06-02 17:13:40 +00:00
CNetEvent_Explosion * pEvent = ( CNetEvent_Explosion * ) m_Events . Create ( NETEVENTTYPE_EXPLOSION , sizeof ( CNetEvent_Explosion ) , Mask ) ;
2011-02-12 10:40:36 +00:00
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
}
2011-02-23 07:43:05 +00:00
/*
2010-05-29 07:25:38 +00:00
if ( ! NoDamage )
2008-08-14 18:42:47 +00:00
{
2011-02-23 07:43:05 +00:00
*/
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 ;
2011-01-29 00:59:50 +00:00
vec2 ForceDir ( 0 , 1 ) ;
2010-05-29 07:25:38 +00:00
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 ) ;
2014-04-13 14:41:02 +00:00
float Strength ;
2014-05-20 15:25:47 +00:00
if ( Owner = = - 1 | | ! m_apPlayers [ Owner ] | | ! m_apPlayers [ Owner ] - > m_TuneZone )
2014-04-13 14:41:02 +00:00
Strength = Tuning ( ) - > m_ExplosionStrength ;
else
2014-04-13 14:49:58 +00:00
Strength = TuningList ( ) [ m_apPlayers [ Owner ] - > m_TuneZone ] . m_ExplosionStrength ;
2014-04-13 14:41:02 +00:00
float Dmg = Strength * l ;
2010-05-29 07:25:38 +00:00
if ( ( int ) Dmg )
2011-07-25 20:16:20 +00:00
if ( ( GetPlayerChar ( Owner ) ? ! ( GetPlayerChar ( Owner ) - > m_Hit & CCharacter : : DISABLE_HIT_GRENADE ) : g_Config . m_SvHit | | NoDamage ) | | Owner = = apEnts [ i ] - > GetPlayer ( ) - > GetCID ( ) )
2010-08-29 02:00:21 +00:00
{
2011-01-29 00:59:50 +00:00
if ( Owner ! = - 1 & & apEnts [ i ] - > IsAlive ( ) & & ! apEnts [ i ] - > CanCollide ( Owner ) ) continue ;
if ( Owner = = - 1 & & ActivatedTeam ! = - 1 & & apEnts [ i ] - > IsAlive ( ) & & apEnts [ i ] - > Team ( ) ! = ActivatedTeam ) continue ;
2010-07-29 05:21:18 +00:00
apEnts [ i ] - > TakeDamage ( ForceDir * Dmg * 2 , ( int ) Dmg , Owner , Weapon ) ;
2011-07-25 20:16:20 +00:00
if ( GetPlayerChar ( Owner ) ? GetPlayerChar ( Owner ) - > m_Hit & CCharacter : : DISABLE_HIT_GRENADE : ! g_Config . m_SvHit | | NoDamage ) break ;
2010-07-29 05:21:18 +00:00
}
2008-08-14 18:42:47 +00:00
}
2011-02-23 07:43:05 +00:00
//}
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
}
} */
2013-12-31 05:13:57 +00:00
void CGameContext : : CreatePlayerSpawn ( vec2 Pos , int64_t Mask )
2008-08-14 18:42:47 +00:00
{
// create the event
2011-06-02 17:13:40 +00:00
CNetEvent_Spawn * ev = ( CNetEvent_Spawn * ) m_Events . Create ( NETEVENTTYPE_SPAWN , sizeof ( CNetEvent_Spawn ) , Mask ) ;
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
}
}
2013-12-31 05:13:57 +00:00
void CGameContext : : CreateDeath ( vec2 Pos , int ClientID , int64_t Mask )
2008-08-14 18:42:47 +00:00
{
// create the event
2011-06-02 17:13:40 +00:00
CNetEvent_Death * pEvent = ( CNetEvent_Death * ) m_Events . Create ( NETEVENTTYPE_DEATH , sizeof ( CNetEvent_Death ) , Mask ) ;
2011-02-12 10:40:36 +00:00
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
}
}
2013-12-31 05:13:57 +00:00
void CGameContext : : CreateSound ( vec2 Pos , int Sound , int64_t Mask )
2008-08-14 18:42:47 +00:00
{
2011-01-29 00:59:50 +00:00
if ( Sound < 0 )
2008-08-14 18:42:47 +00:00
return ;
// create a sound
2011-06-01 17:43:48 +00:00
CNetEvent_SoundWorld * pEvent = ( CNetEvent_SoundWorld * ) m_Events . Create ( NETEVENTTYPE_SOUNDWORLD , sizeof ( CNetEvent_SoundWorld ) , Mask ) ;
2011-02-12 10:40:36 +00:00
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
{
2011-01-29 00:59:50 +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 ;
2011-12-29 12:56:24 +00:00
if ( Target = = - 2 )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_NOSEND , - 1 ) ;
else
{
int Flag = MSGFLAG_VITAL ;
if ( Target ! = - 1 )
Flag | = MSGFLAG_NORECORD ;
Server ( ) - > SendPackMsg ( & Msg , Flag , Target ) ;
}
2008-08-14 18:42:47 +00:00
}
2016-01-19 13:58:52 +00:00
void CGameContext : : CallVote ( int ClientID , const char * pDesc , const char * pCmd , const char * pReason , const char * pChatmsg )
2014-02-19 20:22:36 +00:00
{
// check if a vote is already running
if ( m_VoteCloseTime )
return ;
int64 Now = Server ( ) - > Tick ( ) ;
CPlayer * pPlayer = m_apPlayers [ ClientID ] ;
2014-05-18 23:57:52 +00:00
if ( ! pPlayer )
return ;
2016-01-19 13:58:52 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , pChatmsg ) ;
StartVote ( pDesc , pCmd , pReason ) ;
2014-02-19 20:22:36 +00:00
pPlayer - > m_Vote = 1 ;
pPlayer - > m_VotePos = m_VotePos = 1 ;
m_VoteCreator = ClientID ;
pPlayer - > m_LastVoteCall = Now ;
}
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 ;
2014-09-26 00:40:58 +00:00
if ( g_Config . m_SvDemoChat )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , To ) ;
else
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NORECORD , To ) ;
2009-01-11 14:28:35 +00:00
}
2014-07-26 12:46:31 +00:00
void CGameContext : : SendChatTeam ( int Team , const char * pText )
{
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
if ( ( ( CGameControllerDDRace * ) m_pController ) - > m_Teams . m_Core . Team ( i ) = = Team )
SendChatTarget ( i , pText ) ;
}
2011-02-13 05:35:13 +00:00
void CGameContext : : SendChat ( int ChatterClientID , int Team , const char * pText , int SpamProtectionClientID )
2008-08-14 18:42:47 +00:00
{
2011-02-13 05:35:13 +00:00
if ( SpamProtectionClientID > = 0 & & SpamProtectionClientID < MAX_CLIENTS )
2010-12-07 17:44:23 +00:00
{
2011-02-23 21:39:53 +00:00
if ( ProcessSpamProtection ( SpamProtectionClientID ) )
2011-02-27 08:07:57 +00:00
{
2013-09-02 19:30:00 +00:00
//SendChatTarget(SpamProtectionClientID, "Muted text:");
//SendChatTarget(SpamProtectionClientID, pText);
2010-11-10 21:42:29 +00:00
return ;
2011-02-27 08:07:57 +00:00
}
2010-12-07 17:44:23 +00:00
}
2010-11-10 21:42:29 +00:00
2011-04-09 06:41:31 +00:00
char aBuf [ 256 ] , aText [ 256 ] ;
2010-11-19 16:57:53 +00:00
str_copy ( aText , pText , sizeof ( aText ) ) ;
2011-02-12 10:40:36 +00:00
if ( ChatterClientID > = 0 & & ChatterClientID < MAX_CLIENTS )
2011-02-13 05:35:13 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %d:%d:%s: %s " , ChatterClientID , Team , Server ( ) - > ClientName ( ChatterClientID ) , aText ) ;
else if ( ChatterClientID = = - 2 )
2010-11-19 16:57:53 +00:00
{
str_format ( aBuf , sizeof ( aBuf ) , " ### %s " , aText ) ;
str_copy ( aText , aBuf , sizeof ( aText ) ) ;
2011-02-13 05:35:13 +00:00
ChatterClientID = - 1 ;
2010-11-19 16:57:53 +00:00
}
2008-08-14 18:42:47 +00:00
else
2010-11-19 16:57:53 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " *** %s " , aText ) ;
2011-05-05 00:08:39 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , Team ! = CHAT_ALL ? " teamchat " : " 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 ;
2011-04-09 06:41:31 +00:00
Msg . m_pMessage = aText ;
2013-12-22 17:30:13 +00:00
// pack one for the recording only
2014-09-26 00:40:58 +00:00
if ( g_Config . m_SvDemoChat )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NOSEND , - 1 ) ;
2013-12-22 17:30:13 +00:00
// send to the clients
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] ! = 0 ) {
if ( ! m_apPlayers [ i ] - > m_DND )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NORECORD , i ) ;
}
}
2008-08-14 18:42:47 +00:00
}
else
{
2010-10-06 20:35:19 +00:00
CTeamsCore * Teams = & ( ( CGameControllerDDRace * ) m_pController ) - > m_Teams . m_Core ;
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 ;
2011-04-09 06:41:31 +00:00
Msg . m_pMessage = aText ;
2011-04-13 18:37:12 +00:00
2009-06-15 13:01:04 +00:00
// pack one for the recording only
2014-09-26 00:40:58 +00:00
if ( g_Config . m_SvDemoChat )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NOSEND , - 1 ) ;
2011-01-29 00:59:50 +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-10-06 20:35:19 +00:00
if ( m_apPlayers [ i ] ! = 0 ) {
if ( Team = = CHAT_SPEC ) {
if ( m_apPlayers [ i ] - > GetTeam ( ) = = CHAT_SPEC ) {
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NORECORD , i ) ;
}
} else {
2011-01-17 00:01:11 +00:00
if ( Teams - > Team ( i ) = = Team & & m_apPlayers [ i ] - > GetTeam ( ) ! = CHAT_SPEC ) {
2010-10-06 20:35:19 +00:00
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
}
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
{
// reset votes
2010-05-29 07:25:38 +00:00
m_VoteEnforce = VOTE_ENFORCE_UNKNOWN ;
2011-12-26 09:15:43 +00:00
m_VoteEnforcer = - 1 ;
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
}
2011-04-13 18:37:12 +00:00
2008-09-24 14:47:03 +00:00
// start vote
2014-05-19 00:23:01 +00:00
m_VoteCloseTime = time_get ( ) + time_freq ( ) * g_Config . m_SvVoteTime ;
2010-05-29 07:25:38 +00:00
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
{
2014-01-30 15:54:58 +00:00
if ( Total > VANILLA_MAX_CLIENTS & & m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > m_ClientVersion < = VERSION_DDRACE )
2014-01-02 20:23:27 +00:00
{
Yes = float ( Yes ) * VANILLA_MAX_CLIENTS / float ( Total ) ;
2014-01-03 12:51:18 +00:00
No = float ( No ) * VANILLA_MAX_CLIENTS / float ( Total ) ;
2014-01-02 20:23:27 +00:00
Total = VANILLA_MAX_CLIENTS ;
}
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 ) ;
2011-04-13 18:37:12 +00:00
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-06-09 20:31:55 +00:00
if ( m_VoteCloseTime & & ( ( ! str_comp_num ( m_aVoteCommand , " kick " , 5 ) & & str_toint ( & m_aVoteCommand [ 5 ] ) = = ClientID ) | |
( ! str_comp_num ( m_aVoteCommand , " set_team " , 9 ) & & str_toint ( & m_aVoteCommand [ 9 ] ) = = 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 ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
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
{
2011-01-29 00:59:50 +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 " ) ;
2011-01-29 00:59:50 +00:00
m_Tuning = p ;
2008-09-24 14:47:03 +00:00
}
2011-04-13 18:37:12 +00:00
}
2008-09-24 14:47:03 +00:00
}
2014-03-12 23:31:50 +00:00
void CGameContext : : SendTuningParams ( int ClientID , int Zone )
2008-10-21 17:26:32 +00:00
{
2014-03-29 13:54:43 +00:00
if ( ClientID = = - 1 )
{
2017-04-22 17:04:16 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( m_apPlayers [ i ] )
2014-03-29 13:54:43 +00:00
{
2017-04-22 17:04:16 +00:00
if ( m_apPlayers [ i ] - > GetCharacter ( ) )
2014-03-29 13:54:43 +00:00
{
2017-04-22 17:04:16 +00:00
if ( m_apPlayers [ i ] - > GetCharacter ( ) - > m_TuneZone = = Zone )
2014-03-29 13:54:43 +00:00
SendTuningParams ( i , Zone ) ;
2017-04-22 17:04:16 +00:00
}
else if ( m_apPlayers [ i ] - > m_TuneZone = = Zone )
{
SendTuningParams ( i , Zone ) ;
2014-03-29 13:54:43 +00:00
}
}
2017-04-22 17:04:16 +00:00
}
return ;
2014-03-29 13:54:43 +00:00
}
2015-07-09 00:08:14 +00:00
2010-05-29 07:25:38 +00:00
CheckPureTuning ( ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
CMsgPacker Msg ( NETMSGTYPE_SV_TUNEPARAMS ) ;
2014-03-12 23:31:50 +00:00
int * pParams = 0 ;
if ( Zone = = 0 )
pParams = ( int * ) & m_Tuning ;
else
2017-07-26 01:58:00 +00:00
pParams = ( int * ) & ( m_aTuningList [ Zone ] ) ;
2014-06-26 15:37:06 +00:00
2014-04-12 09:12:29 +00:00
unsigned int last = sizeof ( m_Tuning ) / sizeof ( int ) ;
if ( m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > m_ClientVersion < VERSION_DDNET_EXTRATUNES )
last = 33 ;
2014-12-27 11:05:02 +00:00
else if ( m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > m_ClientVersion < VERSION_DDNET_HOOKDURATION_TUNE )
last = 37 ;
2015-02-12 14:20:22 +00:00
else if ( m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > m_ClientVersion < VERSION_DDNET_FIREDELAY_TUNE )
last = 38 ;
2014-06-26 15:37:06 +00:00
2014-04-12 09:12:29 +00:00
for ( unsigned i = 0 ; i < last ; i + + )
2017-04-22 17:04:16 +00:00
{
if ( m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > GetCharacter ( ) )
2014-02-19 20:55:37 +00:00
{
2017-04-22 17:04:16 +00:00
if ( ( i = = 31 ) // collision
& & ( m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_SOLO
| | m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_NOCOLL ) )
2014-02-19 20:55:37 +00:00
{
2017-04-22 17:04:16 +00:00
Msg . AddInt ( 0 ) ;
}
else if ( ( i = = 32 ) // hooking
& & ( m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_SOLO
| | m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_NOHOOK ) )
{
Msg . AddInt ( 0 ) ;
}
else if ( ( i = = 3 ) // ground jump impulse
& & m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_NOJUMP )
{
Msg . AddInt ( 0 ) ;
}
else if ( ( i = = 33 ) // jetpack
& & ! ( m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_JETPACK ) )
{
Msg . AddInt ( 0 ) ;
}
else if ( ( i = = 36 ) // hammer hit
& & m_apPlayers [ ClientID ] - > GetCharacter ( ) - > NeededFaketuning ( ) & FAKETUNE_NOHAMMER )
{
Msg . AddInt ( 0 ) ;
2014-02-19 21:30:57 +00:00
}
2014-02-19 20:55:37 +00:00
else
2017-04-22 17:04:16 +00:00
{
Msg . AddInt ( pParams [ i ] ) ;
}
2014-02-19 20:55:37 +00:00
}
2017-04-22 17:04:16 +00:00
else
Msg . AddInt ( pParams [ i ] ) ; // if everything is normal just send true tunings
}
Server ( ) - > SendMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
2008-10-21 17:26:32 +00:00
}
2011-12-31 22:00:00 +00:00
/*
2011-12-30 21:47:26 +00:00
void CGameContext : : SwapTeams ( )
{
if ( ! m_pController - > IsTeamplay ( ) )
return ;
2015-07-09 00:08:14 +00:00
2011-12-30 21:47:26 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Teams were swapped " ) ;
2008-10-21 17:26:32 +00:00
2011-12-30 21:47:26 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > GetTeam ( ) ! = TEAM_SPECTATORS )
m_apPlayers [ i ] - > SetTeam ( m_apPlayers [ i ] - > GetTeam ( ) ^ 1 , false ) ;
}
( void ) m_pController - > CheckTeamBalance ( ) ;
}
2011-12-31 22:00:00 +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 ( ) ;
2017-09-12 12:58:44 +00:00
if ( m_TeeHistorianActive )
{
2017-10-13 00:48:42 +00:00
int Error = aio_error ( m_pTeeHistorianFile ) ;
2017-10-10 02:07:38 +00:00
if ( Error )
{
dbg_msg ( " teehistorian " , " error writing to file, err=%d " , Error ) ;
2017-10-13 00:25:50 +00:00
Server ( ) - > SetErrorShutdown ( " teehistorian io error " ) ;
2017-10-10 02:07:38 +00:00
}
2017-09-12 12:58:44 +00:00
if ( ! m_TeeHistorian . Starting ( ) )
{
m_TeeHistorian . EndInputs ( ) ;
m_TeeHistorian . EndTick ( ) ;
}
m_TeeHistorian . BeginTick ( Server ( ) - > Tick ( ) ) ;
m_TeeHistorian . BeginPlayers ( ) ;
}
2010-05-29 07:25:38 +00:00
// copy tuning
2014-04-29 01:34:23 +00:00
m_World . m_Core . m_Tuning [ 0 ] = m_Tuning ;
2010-05-29 07:25:38 +00:00
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 ( ) ;
2011-04-13 18:37:12 +00:00
2017-09-12 12:58:44 +00:00
if ( m_TeeHistorianActive )
{
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > GetCharacter ( ) )
{
CNetObj_CharacterCore Char ;
m_apPlayers [ i ] - > GetCharacter ( ) - > GetCore ( ) . Write ( & Char ) ;
m_TeeHistorian . RecordPlayer ( i , & Char ) ;
}
else
{
m_TeeHistorian . RecordDeadPlayer ( i ) ;
}
}
m_TeeHistorian . EndPlayers ( ) ;
m_TeeHistorian . BeginInputs ( ) ;
}
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
{
2014-10-26 18:39:42 +00:00
// send vote options
ProgressVoteOptions ( i ) ;
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
}
2011-04-13 18:37:12 +00:00
2016-03-04 21:55:12 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] )
m_apPlayers [ i ] - > PostPostTick ( ) ;
}
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 ;
2015-07-08 15:03:22 +00:00
bool Veto = false , VetoStop = false ;
2010-05-29 07:25:38 +00:00
if ( m_VoteUpdate )
2008-09-24 14:47:03 +00:00
{
2010-05-29 07:25:38 +00:00
// count votes
2011-03-28 18:11:28 +00:00
char aaBuf [ MAX_CLIENTS ] [ NETADDR_MAXSTRSIZE ] = { { 0 } } ;
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
if ( m_apPlayers [ i ] )
2011-03-28 18:11:28 +00:00
Server ( ) - > GetClientAddr ( i , aaBuf [ i ] , NETADDR_MAXSTRSIZE ) ;
2010-05-29 07:25:38 +00:00
bool aVoteChecked [ MAX_CLIENTS ] = { 0 } ;
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
2008-10-21 17:26:32 +00:00
{
2011-04-09 06:41:31 +00:00
//if(!m_apPlayers[i] || m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS || aVoteChecked[i]) // don't count in votes by spectators
if ( ! m_apPlayers [ i ] | |
( g_Config . m_SvSpectatorVotes = = 0 & &
m_apPlayers [ i ] - > GetTeam ( ) = = TEAM_SPECTATORS ) | |
aVoteChecked [ i ] ) // don't count in votes by spectators if the admin doesn't want it
2010-05-29 07:25:38 +00:00
continue ;
2011-04-09 06:41:31 +00:00
2015-07-08 15:03:22 +00:00
if ( ( m_VoteKick | | m_VoteSpec ) & & ( ( ! m_apPlayers [ i ] | | m_apPlayers [ i ] - > GetTeam ( ) = = TEAM_SPECTATORS ) | |
2015-04-19 12:15:50 +00:00
( GetPlayerChar ( m_VoteCreator ) & & GetPlayerChar ( i ) & &
GetPlayerChar ( m_VoteCreator ) - > Team ( ) ! = GetPlayerChar ( i ) - > Team ( ) ) ) )
2010-05-29 07:25:38 +00:00
continue ;
2011-04-13 18:37:12 +00:00
2015-07-08 14:04:54 +00:00
if ( m_apPlayers [ i ] - > m_Afk & & i ! = m_VoteCreator )
2013-08-18 01:27:30 +00:00
continue ;
2016-09-05 09:38:11 +00:00
// don't count votes by blacklisted clients
2016-09-05 09:53:26 +00:00
if ( g_Config . m_SvDnsblVote & & ! m_pServer - > DnsblWhite ( i ) )
2016-09-05 09:38:11 +00:00
continue ;
2010-05-29 07:25:38 +00:00
int ActVote = m_apPlayers [ i ] - > m_Vote ;
int ActVotePos = m_apPlayers [ i ] - > m_VotePos ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
// 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 + + ;
2015-07-08 15:03:22 +00:00
2016-01-27 01:14:46 +00:00
// veto right for players who have been active on server for long and who're not afk
if ( ! m_VoteKick & & ! m_VoteSpec & & m_apPlayers [ i ] & &
! m_apPlayers [ i ] - > m_Afk & & m_apPlayers [ i ] - > GetTeam ( ) ! = TEAM_SPECTATORS & &
2015-07-08 15:03:22 +00:00
g_Config . m_SvVoteVetoTime & &
2016-07-08 16:28:15 +00:00
( ( Server ( ) - > Tick ( ) - m_apPlayers [ i ] - > m_JoinTick ) / ( Server ( ) - > TickSpeed ( ) * 60 ) > g_Config . m_SvVoteVetoTime | |
2016-07-20 18:56:22 +00:00
( m_apPlayers [ i ] - > GetCharacter ( ) & & ( Server ( ) - > Tick ( ) - m_apPlayers [ i ] - > GetCharacter ( ) - > m_StartTime ) / ( Server ( ) - > TickSpeed ( ) * 60 ) > g_Config . m_SvVoteVetoTime ) ) )
2015-07-08 15:03:22 +00:00
{
if ( ActVote = = 0 )
Veto = true ;
else if ( ActVote < 0 )
VetoStop = true ;
}
2018-01-05 11:04:06 +00:00
// Check if a active moderator has voted.
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > m_Vote ! = 0 & & m_apPlayers [ i ] - > m_Moderating )
{
if ( m_apPlayers [ i ] - > m_Vote = = 1 )
{
Server ( ) - > SetRconCID ( IServer : : RCON_CID_VOTE ) ;
Console ( ) - > ExecuteLine ( m_aVoteCommand ) ;
Server ( ) - > SetRconCID ( IServer : : RCON_CID_SERV ) ;
EndVote ( ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote passed enforced by server moderator " ) ;
return ;
}
else if ( m_apPlayers [ i ] - > m_Vote = = - 1 )
{
EndVote ( ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote failed enforced by server moderator " ) ;
return ;
}
}
2008-10-21 17:26:32 +00:00
}
2010-05-29 07:25:38 +00:00
2014-08-12 11:41:57 +00:00
if ( g_Config . m_SvVoteMaxTotal & & Total > g_Config . m_SvVoteMaxTotal & &
( m_VoteKick | | m_VoteSpec ) )
2014-03-22 18:53:43 +00:00
Total = g_Config . m_SvVoteMaxTotal ;
2018-01-10 13:33:01 +00:00
if ( No > = Total - Total / ( 100.0 / g_Config . m_SvVoteYesPercentage ) )
2010-05-29 07:25:38 +00:00
m_VoteEnforce = VOTE_ENFORCE_NO ;
2011-02-12 20:31:42 +00:00
2015-07-08 15:03:22 +00:00
if ( VetoStop )
m_VoteEnforce = VOTE_ENFORCE_NO ;
2011-02-12 20:31:42 +00:00
m_VoteWillPass = Yes > ( Yes + No ) / ( 100.0 / g_Config . m_SvVoteYesPercentage ) ;
2008-09-24 14:47:03 +00:00
}
2011-04-09 06:41:31 +00:00
2018-01-10 22:46:14 +00:00
if ( Yes = = Total )
m_VoteEnforce = VOTE_ENFORCE_YES ;
2018-01-10 22:44:40 +00:00
if ( time_get ( ) > m_VoteCloseTime )
2015-07-08 15:03:22 +00:00
m_VoteEnforce = ( m_VoteWillPass & & ! Veto ) ? VOTE_ENFORCE_YES : VOTE_ENFORCE_NO ;
2011-04-13 23:27:49 +00:00
2010-05-29 07:25:38 +00:00
if ( m_VoteEnforce = = VOTE_ENFORCE_YES )
{
2018-01-10 13:36:04 +00:00
Server ( ) - > SetRconCID ( IServer : : RCON_CID_VOTE ) ;
Console ( ) - > ExecuteLine ( m_aVoteCommand ) ;
Server ( ) - > SetRconCID ( IServer : : RCON_CID_SERV ) ;
EndVote ( ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote passed " ) ;
if ( m_apPlayers [ m_VoteCreator ] & & ! m_VoteKick & & ! m_VoteSpec )
m_apPlayers [ m_VoteCreator ] - > m_LastVoteCall = 0 ;
2010-05-29 07:25:38 +00:00
}
2010-10-11 11:10:39 +00:00
else if ( m_VoteEnforce = = VOTE_ENFORCE_YES_ADMIN )
{
char aBuf [ 64 ] ;
2014-09-12 18:29:02 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " Vote passed enforced by server moderator " ) ;
2011-11-08 11:06:09 +00:00
Console ( ) - > ExecuteLine ( m_aVoteCommand , m_VoteEnforcer ) ;
2010-10-11 11:10:39 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , aBuf ) ;
EndVote ( ) ;
}
else if ( m_VoteEnforce = = VOTE_ENFORCE_NO_ADMIN )
{
char aBuf [ 64 ] ;
2014-09-12 18:29:02 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " Vote failed enforced by server moderator " ) ;
2010-10-11 11:10:39 +00:00
EndVote ( ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , aBuf ) ;
}
2011-04-09 06:41:31 +00:00
//else if(m_VoteEnforce == VOTE_ENFORCE_NO || time_get() > m_VoteCloseTime)
2011-02-12 20:31:42 +00:00
else if ( m_VoteEnforce = = VOTE_ENFORCE_NO | | ( time_get ( ) > m_VoteCloseTime & & g_Config . m_SvVoteMajority ) )
2010-05-29 07:25:38 +00:00
{
EndVote ( ) ;
2015-07-08 15:03:22 +00:00
if ( VetoStop | | ( m_VoteWillPass & & Veto ) )
2015-07-08 16:09:52 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote failed because of veto. Find an empty server instead " ) ;
2015-07-08 15:03:22 +00:00
else
SendChat ( - 1 , CGameContext : : CHAT_ALL , " Vote failed " ) ;
2010-05-29 07:25:38 +00:00
}
else if ( m_VoteUpdate )
{
m_VoteUpdate = false ;
2014-01-11 21:22:45 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
if ( Server ( ) - > ClientIngame ( i ) )
SendVoteStatus ( i , Total , Yes , No ) ;
2010-05-29 07:25:38 +00:00
}
}
}
2011-02-23 21:39:53 +00:00
for ( int i = 0 ; i < m_NumMutes ; i + + )
{
if ( m_aMutes [ i ] . m_Expire < = Server ( ) - > Tick ( ) )
{
m_NumMutes - - ;
m_aMutes [ i ] = m_aMutes [ m_NumMutes ] ;
}
}
2010-11-22 20:43:22 +00:00
2011-02-23 21:39:53 +00:00
if ( Server ( ) - > Tick ( ) % ( g_Config . m_SvAnnouncementInterval * Server ( ) - > TickSpeed ( ) * 60 ) = = 0 )
2010-11-22 20:43:22 +00:00
{
2017-06-06 03:51:12 +00:00
const char * Line = Server ( ) - > GetAnnouncementLine ( g_Config . m_SvAnnouncementFileName ) ;
2011-02-23 21:39:53 +00:00
if ( Line )
SendChat ( - 1 , CGameContext : : CHAT_ALL , Line ) ;
}
if ( Collision ( ) - > m_NumSwitchers > 0 )
for ( int i = 0 ; i < Collision ( ) - > m_NumSwitchers + 1 ; + + i )
2010-11-22 20:43:22 +00:00
{
2014-01-01 21:34:10 +00:00
for ( int j = 0 ; j < MAX_CLIENTS ; + + j )
2010-11-22 20:43:22 +00:00
{
2011-02-23 21:39:53 +00:00
if ( Collision ( ) - > m_pSwitchers [ i ] . m_EndTick [ j ] < = Server ( ) - > Tick ( ) & & Collision ( ) - > m_pSwitchers [ i ] . m_Type [ j ] = = TILE_SWITCHTIMEDOPEN )
{
Collision ( ) - > m_pSwitchers [ i ] . m_Status [ j ] = false ;
Collision ( ) - > m_pSwitchers [ i ] . m_EndTick [ j ] = 0 ;
Collision ( ) - > m_pSwitchers [ i ] . m_Type [ j ] = TILE_SWITCHCLOSE ;
}
else if ( Collision ( ) - > m_pSwitchers [ i ] . m_EndTick [ j ] < = Server ( ) - > Tick ( ) & & Collision ( ) - > m_pSwitchers [ i ] . m_Type [ j ] = = TILE_SWITCHTIMEDCLOSE )
{
Collision ( ) - > m_pSwitchers [ i ] . m_Status [ j ] = true ;
Collision ( ) - > m_pSwitchers [ i ] . m_EndTick [ j ] = 0 ;
Collision ( ) - > m_pSwitchers [ i ] . m_Type [ j ] = TILE_SWITCHOPEN ;
}
2010-11-22 20:43:22 +00:00
}
}
2010-05-29 07:25:38 +00:00
# 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 ) ;
}
}
2011-04-13 18:37:12 +00:00
# endif
2010-05-29 07:25:38 +00:00
}
// Server hooks
void CGameContext : : OnClientDirectInput ( int ClientID , void * pInput )
{
if ( ! m_World . m_Paused )
m_apPlayers [ ClientID ] - > OnDirectInput ( ( CNetObj_PlayerInput * ) pInput ) ;
2017-09-12 12:58:44 +00:00
if ( m_TeeHistorianActive )
{
m_TeeHistorian . RecordPlayerInput ( ClientID , ( CNetObj_PlayerInput * ) pInput ) ;
}
2010-05-29 07:25:38 +00:00
}
void CGameContext : : OnClientPredictedInput ( int ClientID , void * pInput )
{
if ( ! m_World . m_Paused )
m_apPlayers [ ClientID ] - > OnPredictedInput ( ( CNetObj_PlayerInput * ) pInput ) ;
}
2015-04-18 20:29:28 +00:00
struct CVoteOptionServer * CGameContext : : GetVoteOption ( int Index )
2014-10-26 18:39:42 +00:00
{
CVoteOptionServer * pCurrent ;
for ( pCurrent = m_pVoteOptionFirst ;
Index > 0 & & pCurrent ;
Index - - , pCurrent = pCurrent - > m_pNext ) ;
if ( Index > 0 )
return 0 ;
return pCurrent ;
}
void CGameContext : : ProgressVoteOptions ( int ClientID )
{
CPlayer * pPl = m_apPlayers [ ClientID ] ;
if ( pPl - > m_SendVoteIndex = = - 1 )
2014-10-27 12:34:29 +00:00
return ; // we didn't start sending options yet
2014-10-26 18:39:42 +00:00
2014-10-27 12:34:29 +00:00
if ( pPl - > m_SendVoteIndex > m_NumVoteOptions )
return ; // shouldn't happen / fail silently
2014-10-26 18:39:42 +00:00
int VotesLeft = m_NumVoteOptions - pPl - > m_SendVoteIndex ;
2014-10-27 12:39:33 +00:00
int NumVotesToSend = min ( g_Config . m_SvSendVotesPerTick , VotesLeft ) ;
2014-10-26 18:39:42 +00:00
if ( ! VotesLeft )
{
// player has up to date vote option list
return ;
}
// build vote option list msg
int CurIndex = 0 ;
CNetMsg_Sv_VoteOptionListAdd OptionMsg ;
OptionMsg . m_pDescription0 = " " ;
OptionMsg . m_pDescription1 = " " ;
OptionMsg . m_pDescription2 = " " ;
OptionMsg . m_pDescription3 = " " ;
OptionMsg . m_pDescription4 = " " ;
OptionMsg . m_pDescription5 = " " ;
OptionMsg . m_pDescription6 = " " ;
OptionMsg . m_pDescription7 = " " ;
OptionMsg . m_pDescription8 = " " ;
OptionMsg . m_pDescription9 = " " ;
OptionMsg . m_pDescription10 = " " ;
OptionMsg . m_pDescription11 = " " ;
OptionMsg . m_pDescription12 = " " ;
OptionMsg . m_pDescription13 = " " ;
OptionMsg . m_pDescription14 = " " ;
// get current vote option by index
CVoteOptionServer * pCurrent = GetVoteOption ( pPl - > m_SendVoteIndex ) ;
2015-06-02 09:55:16 +00:00
while ( CurIndex < NumVotesToSend & & pCurrent ! = NULL )
2014-10-26 18:39:42 +00:00
{
switch ( CurIndex )
{
case 0 : OptionMsg . m_pDescription0 = pCurrent - > m_aDescription ; break ;
case 1 : OptionMsg . m_pDescription1 = pCurrent - > m_aDescription ; break ;
case 2 : OptionMsg . m_pDescription2 = pCurrent - > m_aDescription ; break ;
case 3 : OptionMsg . m_pDescription3 = pCurrent - > m_aDescription ; break ;
case 4 : OptionMsg . m_pDescription4 = pCurrent - > m_aDescription ; break ;
case 5 : OptionMsg . m_pDescription5 = pCurrent - > m_aDescription ; break ;
case 6 : OptionMsg . m_pDescription6 = pCurrent - > m_aDescription ; break ;
case 7 : OptionMsg . m_pDescription7 = pCurrent - > m_aDescription ; break ;
case 8 : OptionMsg . m_pDescription8 = pCurrent - > m_aDescription ; break ;
case 9 : OptionMsg . m_pDescription9 = pCurrent - > m_aDescription ; break ;
case 10 : OptionMsg . m_pDescription10 = pCurrent - > m_aDescription ; break ;
case 11 : OptionMsg . m_pDescription11 = pCurrent - > m_aDescription ; break ;
case 12 : OptionMsg . m_pDescription12 = pCurrent - > m_aDescription ; break ;
case 13 : OptionMsg . m_pDescription13 = pCurrent - > m_aDescription ; break ;
case 14 : OptionMsg . m_pDescription14 = pCurrent - > m_aDescription ; break ;
}
CurIndex + + ;
pCurrent = pCurrent - > m_pNext ;
}
// send msg
OptionMsg . m_NumOptions = NumVotesToSend ;
Server ( ) - > SendPackMsg ( & OptionMsg , MSGFLAG_VITAL , ClientID ) ;
pPl - > m_SendVoteIndex + = NumVotesToSend ;
}
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-09-26 15:18:56 +00:00
// init the player
2011-02-13 05:35:13 +00:00
Score ( ) - > PlayerData ( ClientID ) - > Reset ( ) ;
2013-11-14 15:08:04 +00:00
m_apPlayers [ ClientID ] - > m_Score = - 9999 ;
// Can't set score here as LoadScore() is threaded, run it in
// LoadScoreThreaded() instead
2011-02-13 05:35:13 +00:00
Score ( ) - > LoadScore ( ClientID ) ;
2016-03-25 23:36:54 +00:00
Score ( ) - > CheckBirthday ( ClientID ) ;
2010-09-26 21:31:33 +00:00
2017-06-06 03:51:12 +00:00
if ( ! Server ( ) - > ClientPrevIngame ( ClientID ) )
2011-01-20 20:25:09 +00:00
{
char aBuf [ 512 ] ;
2011-02-13 05:35:13 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " '%s' entered and joined the %s " , Server ( ) - > ClientName ( ClientID ) , m_pController - > GetTeamName ( m_apPlayers [ ClientID ] - > GetTeam ( ) ) ) ;
2011-04-09 06:41:31 +00:00
SendChat ( - 1 , CGameContext : : CHAT_ALL , aBuf ) ;
2011-01-20 20:25:09 +00:00
2013-08-13 16:32:33 +00:00
SendChatTarget ( ClientID , " DDraceNetwork Mod. Version: " GAME_VERSION ) ;
2016-05-20 16:36:32 +00:00
SendChatTarget ( ClientID , " please visit DDNet.tw or say /info for more info " ) ;
2011-01-20 20:25:09 +00:00
2011-08-26 06:09:51 +00:00
if ( g_Config . m_SvWelcome [ 0 ] ! = 0 )
SendChatTarget ( ClientID , g_Config . m_SvWelcome ) ;
str_format ( aBuf , sizeof ( aBuf ) , " team_join player='%d:%s' team=%d " , ClientID , Server ( ) - > ClientName ( ClientID ) , m_apPlayers [ ClientID ] - > GetTeam ( ) ) ;
2010-05-29 07:25:38 +00:00
2011-01-20 20:25:09 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " game " , aBuf ) ;
2011-12-31 17:16:40 +00:00
2013-10-20 21:22:49 +00:00
if ( g_Config . m_SvShowOthersDefault )
{
if ( g_Config . m_SvShowOthers )
2016-05-20 16:36:32 +00:00
SendChatTarget ( ClientID , " You can see other players. To disable this use DDNet client and type /showothers . " ) ;
2013-10-20 21:22:49 +00:00
m_apPlayers [ ClientID ] - > m_ShowOthers = true ;
}
2011-01-20 20:25:09 +00:00
}
2010-05-29 07:25:38 +00:00
m_VoteUpdate = true ;
2011-08-26 18:03:30 +00:00
2014-03-28 11:52:03 +00:00
// send active vote
if ( m_VoteCloseTime )
SendVoteSet ( ClientID ) ;
2011-12-31 17:16:40 +00:00
2017-06-08 19:58:41 +00:00
m_apPlayers [ ClientID ] - > m_Authed = Server ( ) - > GetAuthedState ( ClientID ) ;
2010-05-29 07:25:38 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnClientConnected ( int ClientID )
2010-05-29 07:25:38 +00:00
{
2016-01-19 22:52:28 +00:00
{
bool Empty = true ;
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] )
{
Empty = false ;
break ;
}
}
if ( Empty )
{
m_NonEmptySince = Server ( ) - > Tick ( ) ;
}
}
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
2014-08-18 21:50:24 +00:00
if ( ! m_apPlayers [ ClientID ] )
m_apPlayers [ ClientID ] = new ( ClientID ) CPlayer ( this , ClientID , StartTeam ) ;
else
{
delete m_apPlayers [ ClientID ] ;
m_apPlayers [ ClientID ] = new ( ClientID ) CPlayer ( this , ClientID , StartTeam ) ;
2014-08-16 12:43:22 +00:00
// //m_apPlayers[ClientID]->Reset();
// //((CServer*)Server())->m_aClients[ClientID].Reset();
// ((CServer*)Server())->m_aClients[ClientID].m_State = 4;
2014-08-18 21:50:24 +00:00
}
2010-05-29 07:25:38 +00:00
//players[client_id].init(client_id);
//players[client_id].client_id = client_id;
2011-04-13 18:37:12 +00:00
2010-07-29 05:21:18 +00:00
//(void)m_pController->CheckTeamBalance();
2010-05-29 07:25:38 +00:00
# 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 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-14 18:41:32 +00:00
void CGameContext : : OnClientDrop ( int ClientID , const char * pReason )
2010-05-29 07:25:38 +00:00
{
2011-02-12 10:40:36 +00:00
AbortVoteKickOnDisconnect ( ClientID ) ;
2011-02-14 18:41:32 +00:00
m_apPlayers [ ClientID ] - > OnDisconnect ( pReason ) ;
2011-02-12 10:40:36 +00:00
delete m_apPlayers [ ClientID ] ;
m_apPlayers [ ClientID ] = 0 ;
2011-04-13 18:37:12 +00:00
2010-07-29 05:21:18 +00:00
//(void)m_pController->CheckTeamBalance();
2010-05-29 07:25:38 +00:00
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 ;
}
2013-10-18 09:42:35 +00:00
// update conversation targets
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > m_LastWhisperTo = = ClientID )
m_apPlayers [ i ] - > m_LastWhisperTo = - 1 ;
}
2010-05-29 07:25:38 +00:00
}
2017-09-13 20:35:09 +00:00
void CGameContext : : OnClientEngineJoin ( int ClientID )
{
if ( m_TeeHistorianActive )
{
m_TeeHistorian . RecordPlayerJoin ( ClientID ) ;
}
}
void CGameContext : : OnClientEngineDrop ( int ClientID , const char * pReason )
{
if ( m_TeeHistorianActive )
{
m_TeeHistorian . RecordPlayerDrop ( ClientID , pReason ) ;
}
}
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 ] ;
2011-08-13 00:11:06 +00:00
2017-09-13 20:35:09 +00:00
if ( m_TeeHistorianActive )
{
2017-10-13 14:33:23 +00:00
if ( m_NetObjHandler . TeeHistorianRecordMsg ( MsgID ) )
2017-10-13 14:25:26 +00:00
{
m_TeeHistorian . RecordPlayerMessage ( ClientID , pUnpacker - > CompleteData ( ) , pUnpacker - > CompleteSize ( ) ) ;
}
2017-09-13 20:35:09 +00:00
}
2010-05-29 07:25:38 +00:00
if ( ! pRawMsg )
{
2015-08-05 20:43:57 +00:00
//char aBuf[256];
//str_format(aBuf, sizeof(aBuf), "dropped weird message '%s' (%d), failed on '%s'", m_NetObjHandler.GetMsgName(MsgID), MsgID, m_NetObjHandler.FailedMsgOn());
//Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
2010-05-29 07:25:38 +00:00
return ;
}
2011-04-13 18:37:12 +00:00
2013-03-23 14:59:27 +00:00
if ( Server ( ) - > ClientIngame ( ClientID ) )
2010-05-29 07:25:38 +00:00
{
2013-03-23 14:59:27 +00:00
if ( MsgID = = NETMSGTYPE_CL_SAY )
2010-05-29 07:25:38 +00:00
{
2013-03-23 14:59:27 +00:00
CNetMsg_Cl_Say * pMsg = ( CNetMsg_Cl_Say * ) pRawMsg ;
2016-01-27 00:48:19 +00:00
if ( ! str_utf8_check ( pMsg - > m_pMessage ) )
2016-01-27 00:24:02 +00:00
{
return ;
}
2013-12-26 17:02:22 +00:00
int Team = pMsg - > m_Team ;
2013-12-27 03:09:45 +00:00
// trim right and set maximum length to 256 utf8-characters
2013-04-01 18:30:58 +00:00
int Length = 0 ;
const char * p = pMsg - > m_pMessage ;
const char * pEnd = 0 ;
while ( * p )
2015-07-09 00:08:14 +00:00
{
2013-04-01 18:30:58 +00:00
const char * pStrOld = p ;
int Code = str_utf8_decode ( & p ) ;
// check if unicode is not empty
2014-11-08 19:14:12 +00:00
if ( str_utf8_isspace ( Code ) )
2013-04-01 18:30:58 +00:00
{
pEnd = 0 ;
}
else if ( pEnd = = 0 )
pEnd = pStrOld ;
2011-04-13 18:37:12 +00:00
2013-12-27 03:09:45 +00:00
if ( + + Length > = 256 )
2013-04-01 18:30:58 +00:00
{
* ( const_cast < char * > ( p ) ) = 0 ;
break ;
}
2015-07-09 00:08:14 +00:00
}
2013-04-01 18:30:58 +00:00
if ( pEnd ! = 0 )
* ( const_cast < char * > ( pEnd ) ) = 0 ;
2011-04-09 06:41:31 +00:00
2014-01-01 21:06:46 +00:00
// drop empty and autocreated spam messages (more than 32 characters per second)
2014-02-13 23:26:05 +00:00
if ( Length = = 0 | | ( pMsg - > m_pMessage [ 0 ] ! = ' / ' & & ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastChat & & pPlayer - > m_LastChat + Server ( ) - > TickSpeed ( ) * ( ( 31 + Length ) / 32 ) > Server ( ) - > Tick ( ) ) ) )
2013-03-23 14:59:27 +00:00
return ;
2010-08-20 20:40:12 +00:00
2013-12-26 17:02:22 +00:00
//pPlayer->m_LastChat = Server()->Tick();
int GameTeam = ( ( CGameControllerDDRace * ) m_pController ) - > m_Teams . m_Core . Team ( pPlayer - > GetCID ( ) ) ;
if ( Team )
Team = ( ( pPlayer - > GetTeam ( ) = = - 1 ) ? CHAT_SPEC : GameTeam ) ;
else
Team = CHAT_ALL ;
if ( pMsg - > m_pMessage [ 0 ] = = ' / ' )
2013-08-09 13:04:20 +00:00
{
2013-12-26 17:02:22 +00:00
if ( str_comp_nocase_num ( pMsg - > m_pMessage + 1 , " w " , 2 ) = = 0 )
{
char pWhisperMsg [ 256 ] ;
str_copy ( pWhisperMsg , pMsg - > m_pMessage + 3 , 256 ) ;
Whisper ( pPlayer - > GetCID ( ) , pWhisperMsg ) ;
}
else if ( str_comp_nocase_num ( pMsg - > m_pMessage + 1 , " whisper " , 8 ) = = 0 )
{
char pWhisperMsg [ 256 ] ;
str_copy ( pWhisperMsg , pMsg - > m_pMessage + 9 , 256 ) ;
Whisper ( pPlayer - > GetCID ( ) , pWhisperMsg ) ;
}
else if ( str_comp_nocase_num ( pMsg - > m_pMessage + 1 , " c " , 2 ) = = 0 )
{
char pWhisperMsg [ 256 ] ;
str_copy ( pWhisperMsg , pMsg - > m_pMessage + 3 , 256 ) ;
Converse ( pPlayer - > GetCID ( ) , pWhisperMsg ) ;
}
else if ( str_comp_nocase_num ( pMsg - > m_pMessage + 1 , " converse " , 9 ) = = 0 )
{
char pWhisperMsg [ 256 ] ;
str_copy ( pWhisperMsg , pMsg - > m_pMessage + 10 , 256 ) ;
Converse ( pPlayer - > GetCID ( ) , pWhisperMsg ) ;
}
else
{
2015-06-26 01:59:38 +00:00
if ( g_Config . m_SvSpamprotection & & str_comp_nocase_num ( pMsg - > m_pMessage + 1 , " timeout " , 8 ) ! = 0
2013-12-26 17:02:22 +00:00
& & pPlayer - > m_LastCommands [ 0 ] & & pPlayer - > m_LastCommands [ 0 ] + Server ( ) - > TickSpeed ( ) > Server ( ) - > Tick ( )
& & pPlayer - > m_LastCommands [ 1 ] & & pPlayer - > m_LastCommands [ 1 ] + Server ( ) - > TickSpeed ( ) > Server ( ) - > Tick ( )
& & pPlayer - > m_LastCommands [ 2 ] & & pPlayer - > m_LastCommands [ 2 ] + Server ( ) - > TickSpeed ( ) > Server ( ) - > Tick ( )
& & pPlayer - > m_LastCommands [ 3 ] & & pPlayer - > m_LastCommands [ 3 ] + Server ( ) - > TickSpeed ( ) > Server ( ) - > Tick ( )
)
return ;
2010-08-06 19:03:38 +00:00
2013-12-26 17:02:22 +00:00
int64 Now = Server ( ) - > Tick ( ) ;
pPlayer - > m_LastCommands [ pPlayer - > m_LastCommandPos ] = Now ;
pPlayer - > m_LastCommandPos = ( pPlayer - > m_LastCommandPos + 1 ) % 4 ;
m_ChatResponseTargetID = ClientID ;
Server ( ) - > RestrictRconOutput ( ClientID ) ;
Console ( ) - > SetFlagMask ( CFGFLAG_CHAT ) ;
if ( pPlayer - > m_Authed )
2017-06-06 03:51:12 +00:00
Console ( ) - > SetAccessLevel ( pPlayer - > m_Authed = = IServer : : AUTHED_ADMIN ? IConsole : : ACCESS_LEVEL_ADMIN : pPlayer - > m_Authed = = IServer : : AUTHED_MOD ? IConsole : : ACCESS_LEVEL_MOD : IConsole : : ACCESS_LEVEL_HELPER ) ;
2013-12-26 17:02:22 +00:00
else
Console ( ) - > SetAccessLevel ( IConsole : : ACCESS_LEVEL_USER ) ;
Console ( ) - > SetPrintOutputLevel ( m_ChatPrintCBIndex , 0 ) ;
2017-11-18 15:36:34 +00:00
Console ( ) - > ExecuteLine ( pMsg - > m_pMessage + 1 , ClientID , false ) ;
2017-01-04 17:14:08 +00:00
// m_apPlayers[ClientID] can be NULL, if the player used a
// timeout code and replaced another client.
2013-12-26 17:02:22 +00:00
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %d used %s " , ClientID , pMsg - > m_pMessage ) ;
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " chat-command " , aBuf ) ;
Console ( ) - > SetAccessLevel ( IConsole : : ACCESS_LEVEL_ADMIN ) ;
Console ( ) - > SetFlagMask ( CFGFLAG_SERVER ) ;
m_ChatResponseTargetID = - 1 ;
Server ( ) - > RestrictRconOutput ( - 1 ) ;
}
2013-08-09 13:04:20 +00:00
}
2013-12-26 17:02:22 +00:00
else
SendChat ( ClientID , Team , pMsg - > m_pMessage , ClientID ) ;
2010-05-29 07:25:38 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( MsgID = = NETMSGTYPE_CL_CALLVOTE )
2010-05-29 07:25:38 +00:00
{
2016-01-19 22:52:28 +00:00
int64 Now = Server ( ) - > Tick ( ) ;
int64 TickSpeed = Server ( ) - > TickSpeed ( ) ;
2017-12-27 07:40:51 +00:00
if ( g_Config . m_SvRconVote & & ! pPlayer - > m_Authed )
{
SendChatTarget ( ClientID , " You can only vote after logging in. " ) ;
return ;
}
2016-09-05 09:53:26 +00:00
if ( g_Config . m_SvDnsblVote & & ! m_pServer - > DnsblWhite ( ClientID ) )
2016-09-05 09:38:11 +00:00
{
// blacklisted by dnsbl
2017-12-27 07:40:51 +00:00
SendChatTarget ( ClientID , " You are not allowed to vote due to DNSBL. " ) ;
2016-09-05 09:38:11 +00:00
return ;
}
2016-01-19 22:52:28 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastVoteTry & & pPlayer - > m_LastVoteTry + TickSpeed * 3 > Now )
2013-03-23 14:59:27 +00:00
return ;
2010-05-29 07:25:38 +00:00
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastVoteTry = Now ;
2013-12-26 17:02:22 +00:00
if ( g_Config . m_SvSpectatorVotes = = 0 & & pPlayer - > GetTeam ( ) = = TEAM_SPECTATORS )
2013-10-18 09:42:35 +00:00
{
2013-03-23 14:59:27 +00:00
SendChatTarget ( ClientID , " Spectators aren't allowed to start a vote. " ) ;
return ;
2013-10-18 09:42:35 +00:00
}
2011-04-13 18:37:12 +00:00
2013-03-23 14:59:27 +00:00
if ( m_VoteCloseTime )
2013-10-18 09:42:35 +00:00
{
2013-03-23 14:59:27 +00:00
SendChatTarget ( ClientID , " Wait for current vote to end before calling a new one. " ) ;
2010-05-29 07:25:38 +00:00
return ;
2013-10-18 09:42:35 +00:00
}
2013-08-10 02:21:20 +00:00
2016-05-20 18:05:47 +00:00
if ( Now < pPlayer - > m_FirstVoteTick )
2016-01-19 22:52:28 +00:00
{
char aBuf [ 64 ] ;
2017-12-27 07:40:51 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " You must wait %d seconds before making your first vote. " , ( int ) ( ( pPlayer - > m_FirstVoteTick - Now ) / TickSpeed ) + 1 ) ;
2016-01-19 22:52:28 +00:00
SendChatTarget ( ClientID , aBuf ) ;
return ;
}
int TimeLeft = pPlayer - > m_LastVoteCall + TickSpeed * g_Config . m_SvVoteDelay - Now ;
if ( pPlayer - > m_LastVoteCall & & TimeLeft > 0 )
2008-10-21 17:26:32 +00:00
{
2016-01-19 22:52:28 +00:00
char aChatmsg [ 64 ] ;
2017-12-27 07:40:51 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " You must wait %d seconds before making another vote. " , ( int ) ( TimeLeft / TickSpeed ) + 1 ) ;
2013-03-23 14:59:27 +00:00
SendChatTarget ( ClientID , aChatmsg ) ;
2010-05-29 07:25:38 +00:00
return ;
2013-08-09 13:04:20 +00:00
}
2010-05-29 07:25:38 +00:00
2013-03-23 14:59:27 +00:00
char aChatmsg [ 512 ] = { 0 } ;
char aDesc [ VOTE_DESC_LENGTH ] = { 0 } ;
char aCmd [ VOTE_CMD_LENGTH ] = { 0 } ;
2016-01-19 13:59:16 +00:00
char aReason [ VOTE_REASON_LENGTH ] = " No reason given " ;
2013-03-23 14:59:27 +00:00
CNetMsg_Cl_CallVote * pMsg = ( CNetMsg_Cl_CallVote * ) pRawMsg ;
2016-01-27 00:48:19 +00:00
if ( ! str_utf8_check ( pMsg - > m_Type )
| | ! str_utf8_check ( pMsg - > m_Reason )
| | ! str_utf8_check ( pMsg - > m_Value ) )
2016-01-27 00:24:02 +00:00
{
return ;
}
2016-01-19 13:59:16 +00:00
if ( pMsg - > m_Reason [ 0 ] )
{
str_copy ( aReason , pMsg - > m_Reason , sizeof ( aReason ) ) ;
}
2010-08-06 19:03:38 +00:00
2013-03-23 14:59:27 +00:00
if ( str_comp_nocase ( pMsg - > m_Type , " option " ) = = 0 )
2011-03-04 16:35:50 +00:00
{
2013-03-23 14:59:27 +00:00
CVoteOptionServer * pOption = m_pVoteOptionFirst ;
while ( pOption )
{
if ( str_comp_nocase ( pMsg - > m_Value , pOption - > m_aDescription ) = = 0 )
{
2013-12-26 17:02:22 +00:00
if ( ! Console ( ) - > LineIsValid ( pOption - > m_aCommand ) )
{
SendChatTarget ( ClientID , " Invalid option " ) ;
return ;
}
2017-12-27 07:40:51 +00:00
if ( ! pPlayer - > m_Authed & & ( str_comp_num ( pOption - > m_aCommand , " sv_map " , 7 ) = = 0 | | str_comp_num ( pOption - > m_aCommand , " change_map " , 11 ) = = 0 | | str_comp_num ( pOption - > m_aCommand , " random_map " , 10 ) = = 0 | | str_comp_num ( pOption - > m_aCommand , " random_unfinished_map " , 21 ) = = 0 ) & & time_get ( ) < m_LastMapVote + ( time_freq ( ) * g_Config . m_SvVoteMapTimeDelay ) )
2013-12-26 17:02:22 +00:00
{
2017-07-26 01:58:00 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " There's a %d second delay between map-votes, please wait %d seconds. " , g_Config . m_SvVoteMapTimeDelay , ( int ) ( ( ( m_LastMapVote + ( g_Config . m_SvVoteMapTimeDelay * time_freq ( ) ) ) / time_freq ( ) ) - ( time_get ( ) / time_freq ( ) ) ) ) ;
SendChatTarget ( ClientID , aChatmsg ) ;
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
return ;
}
2014-10-10 22:41:56 +00:00
2013-03-23 14:59:27 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called vote to change server option '%s' (%s) " , Server ( ) - > ClientName ( ClientID ) ,
2016-01-19 13:59:16 +00:00
pOption - > m_aDescription , aReason ) ;
2013-03-23 14:59:27 +00:00
str_format ( aDesc , sizeof ( aDesc ) , " %s " , pOption - > m_aDescription ) ;
2014-10-10 22:41:56 +00:00
2016-01-19 13:59:16 +00:00
if ( ( str_comp_num ( pOption - > m_aCommand , " random_map " , 10 ) = = 0 | | str_comp_num ( pOption - > m_aCommand , " random_unfinished_map " , 21 ) = = 0 ) & & str_length ( aReason ) = = 1 & & aReason [ 0 ] > = ' 1 ' & & aReason [ 0 ] < = ' 5 ' )
2014-10-10 22:41:56 +00:00
{
2016-01-19 13:59:16 +00:00
int stars = aReason [ 0 ] - ' 0 ' ;
2014-10-10 22:41:56 +00:00
str_format ( aCmd , sizeof ( aCmd ) , " %s %d " , pOption - > m_aCommand , stars ) ;
}
else
{
str_format ( aCmd , sizeof ( aCmd ) , " %s " , pOption - > m_aCommand ) ;
}
2017-05-17 16:50:01 +00:00
m_LastMapVote = time_get ( ) ;
2013-03-23 14:59:27 +00:00
break ;
}
2011-04-13 18:37:12 +00:00
2013-03-23 14:59:27 +00:00
pOption = pOption - > m_pNext ;
}
2011-03-25 09:26:59 +00:00
2013-03-23 14:59:27 +00:00
if ( ! pOption )
2010-05-29 07:25:38 +00:00
{
2017-06-06 03:51:12 +00:00
if ( pPlayer - > m_Authed ! = IServer : : AUTHED_ADMIN ) // allow admins to call any vote they want
2011-01-21 13:40:39 +00:00
{
2013-12-26 17:02:22 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' isn't an option on this server " , pMsg - > m_Value ) ;
SendChatTarget ( ClientID , aChatmsg ) ;
2011-01-21 13:40:39 +00:00
return ;
}
2013-12-26 17:02:22 +00:00
else
2011-04-09 06:41:31 +00:00
{
2013-12-26 17:02:22 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called vote to change server option '%s' " , Server ( ) - > ClientName ( ClientID ) , pMsg - > m_Value ) ;
str_format ( aDesc , sizeof ( aDesc ) , " %s " , pMsg - > m_Value ) ;
str_format ( aCmd , sizeof ( aCmd ) , " %s " , pMsg - > m_Value ) ;
}
2011-03-04 16:35:50 +00:00
}
2010-08-20 20:40:12 +00:00
2013-12-26 17:02:22 +00:00
m_VoteKick = false ;
2014-08-12 11:41:57 +00:00
m_VoteSpec = false ;
2011-03-04 16:35:50 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( str_comp_nocase ( pMsg - > m_Type , " kick " ) = = 0 )
2010-05-29 07:25:38 +00:00
{
2013-12-26 17:02:22 +00:00
if ( ! m_apPlayers [ ClientID ] - > m_Authed & & time_get ( ) < m_apPlayers [ ClientID ] - > m_Last_KickVote + ( time_freq ( ) * 5 ) )
return ;
2017-04-24 15:36:13 +00:00
else if ( ! m_apPlayers [ ClientID ] - > m_Authed & & time_get ( ) < m_apPlayers [ ClientID ] - > m_Last_KickVote + ( time_freq ( ) * g_Config . m_SvVoteKickDelay ) )
2013-12-26 17:02:22 +00:00
{
2017-07-26 01:58:00 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " There's a %d second wait time between kick votes for each player please wait %d second(s) " ,
2017-04-24 15:36:13 +00:00
g_Config . m_SvVoteKickDelay ,
2017-07-26 01:58:00 +00:00
( int ) ( ( ( m_apPlayers [ ClientID ] - > m_Last_KickVote + ( m_apPlayers [ ClientID ] - > m_Last_KickVote * time_freq ( ) ) ) / time_freq ( ) ) - ( time_get ( ) / time_freq ( ) ) )
2013-12-26 17:02:22 +00:00
) ;
2017-07-26 01:58:00 +00:00
SendChatTarget ( ClientID , aChatmsg ) ;
2013-12-26 17:02:22 +00:00
m_apPlayers [ ClientID ] - > m_Last_KickVote = time_get ( ) ;
return ;
}
//else if(!g_Config.m_SvVoteKick)
else if ( ! g_Config . m_SvVoteKick & & ! pPlayer - > m_Authed ) // allow admins to call kick votes even if they are forbidden
2013-03-23 14:59:27 +00:00
{
SendChatTarget ( ClientID , " Server does not allow voting to kick players " ) ;
2013-12-26 17:02:22 +00:00
m_apPlayers [ ClientID ] - > m_Last_KickVote = time_get ( ) ;
2013-03-23 14:59:27 +00:00
return ;
}
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 ) ;
2011-04-09 06:41:31 +00:00
return ;
}
2010-05-29 07:25:38 +00:00
}
2013-03-23 14:59:27 +00:00
int KickID = str_toint ( pMsg - > m_Value ) ;
2013-12-31 17:25:40 +00:00
2013-03-23 14:59:27 +00:00
if ( KickID < 0 | | KickID > = MAX_CLIENTS | | ! m_apPlayers [ KickID ] )
{
SendChatTarget ( ClientID , " Invalid client id to kick " ) ;
return ;
}
if ( KickID = = ClientID )
{
SendChatTarget ( ClientID , " You can't kick yourself " ) ;
return ;
}
2015-08-12 13:54:03 +00:00
if ( ! Server ( ) - > ReverseTranslate ( KickID , ClientID ) )
{
return ;
}
2013-12-26 17:02:22 +00:00
//if(Server()->IsAuthed(KickID))
if ( m_apPlayers [ KickID ] - > m_Authed > 0 & & m_apPlayers [ KickID ] - > m_Authed > = pPlayer - > m_Authed )
2013-03-23 14:59:27 +00:00
{
2014-10-28 20:37:46 +00:00
SendChatTarget ( ClientID , " You can't kick moderators " ) ;
2013-12-26 17:02:22 +00:00
m_apPlayers [ ClientID ] - > m_Last_KickVote = time_get ( ) ;
2013-03-23 14:59:27 +00:00
char aBufKick [ 128 ] ;
str_format ( aBufKick , sizeof ( aBufKick ) , " '%s' called for vote to kick you " , Server ( ) - > ClientName ( ClientID ) ) ;
SendChatTarget ( KickID , aBufKick ) ;
return ;
}
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
// Don't allow kicking if a player has no character
if ( ! GetPlayerChar ( ClientID ) | | ! GetPlayerChar ( KickID ) | | GetDDRaceTeam ( ClientID ) ! = GetDDRaceTeam ( KickID ) )
2010-10-11 09:18:44 +00:00
{
2013-12-26 17:02:22 +00:00
SendChatTarget ( ClientID , " You can kick only your team member " ) ;
m_apPlayers [ ClientID ] - > m_Last_KickVote = time_get ( ) ;
2010-10-11 09:18:44 +00:00
return ;
}
2013-12-26 17:02:22 +00:00
2016-01-19 13:59:16 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called for vote to kick '%s' (%s) " , Server ( ) - > ClientName ( ClientID ) , Server ( ) - > ClientName ( KickID ) , aReason ) ;
2013-03-23 14:59:27 +00:00
str_format ( aDesc , sizeof ( aDesc ) , " Kick '%s' " , Server ( ) - > ClientName ( KickID ) ) ;
2017-04-25 17:10:22 +00:00
if ( ! GetDDRaceTeam ( ClientID ) )
{
if ( ! g_Config . m_SvVoteKickBantime )
str_format ( aCmd , sizeof ( aCmd ) , " kick %d Kicked by vote " , KickID ) ;
else
{
char aAddrStr [ NETADDR_MAXSTRSIZE ] = { 0 } ;
Server ( ) - > GetClientAddr ( KickID , aAddrStr , sizeof ( aAddrStr ) ) ;
str_format ( aCmd , sizeof ( aCmd ) , " ban %s %d Banned by vote " , aAddrStr , g_Config . m_SvVoteKickBantime ) ;
}
}
2010-10-11 09:18:44 +00:00
else
{
2017-04-25 17:10:22 +00:00
str_format ( aCmd , sizeof ( aCmd ) , " set_team_ddr %d 0 " , KickID ) ;
2010-10-11 09:18:44 +00:00
}
2011-02-13 05:35:13 +00:00
m_apPlayers [ ClientID ] - > m_Last_KickVote = time_get ( ) ;
2013-12-26 17:02:22 +00:00
m_VoteKick = true ;
2014-08-12 11:41:57 +00:00
m_VoteSpec = false ;
2010-07-29 19:55:33 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( str_comp_nocase ( pMsg - > m_Type , " spectate " ) = = 0 )
2008-10-21 17:26:32 +00:00
{
2013-03-23 14:59:27 +00:00
if ( ! g_Config . m_SvVoteSpectate )
{
SendChatTarget ( ClientID , " Server does not allow voting to move players to spectators " ) ;
return ;
}
2011-03-04 16:35:50 +00:00
2013-03-23 14:59:27 +00:00
int SpectateID = str_toint ( pMsg - > m_Value ) ;
2013-12-31 17:25:40 +00:00
2013-03-23 14:59:27 +00:00
if ( SpectateID < 0 | | SpectateID > = MAX_CLIENTS | | ! m_apPlayers [ SpectateID ] | | m_apPlayers [ SpectateID ] - > GetTeam ( ) = = TEAM_SPECTATORS )
{
SendChatTarget ( ClientID , " Invalid client id to move " ) ;
return ;
}
if ( SpectateID = = ClientID )
{
SendChatTarget ( ClientID , " You can't move yourself " ) ;
return ;
}
2015-08-12 13:54:03 +00:00
if ( ! Server ( ) - > ReverseTranslate ( SpectateID , ClientID ) )
{
return ;
}
2011-03-04 16:35:50 +00:00
2013-12-26 17:02:22 +00:00
if ( ! GetPlayerChar ( ClientID ) | | ! GetPlayerChar ( SpectateID ) | | GetDDRaceTeam ( ClientID ) ! = GetDDRaceTeam ( SpectateID ) )
2011-03-04 16:35:50 +00:00
{
2013-12-26 17:02:22 +00:00
SendChatTarget ( ClientID , " You can only move your team member to specators " ) ;
2011-03-04 16:35:50 +00:00
return ;
}
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
if ( g_Config . m_SvPauseable & & g_Config . m_SvVotePause )
{
2016-01-19 13:59:16 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called for vote to pause '%s' for %d seconds (%s) " , Server ( ) - > ClientName ( ClientID ) , Server ( ) - > ClientName ( SpectateID ) , g_Config . m_SvVotePauseTime , aReason ) ;
2013-12-26 17:02:22 +00:00
str_format ( aDesc , sizeof ( aDesc ) , " Pause '%s' (%ds) " , Server ( ) - > ClientName ( SpectateID ) , g_Config . m_SvVotePauseTime ) ;
str_format ( aCmd , sizeof ( aCmd ) , " force_pause %d %d " , SpectateID , g_Config . m_SvVotePauseTime ) ;
}
else
{
2016-01-19 13:59:16 +00:00
str_format ( aChatmsg , sizeof ( aChatmsg ) , " '%s' called for vote to move '%s' to spectators (%s) " , Server ( ) - > ClientName ( ClientID ) , Server ( ) - > ClientName ( SpectateID ) , aReason ) ;
2013-12-26 17:02:22 +00:00
str_format ( aDesc , sizeof ( aDesc ) , " move '%s' to spectators " , Server ( ) - > ClientName ( SpectateID ) ) ;
2013-03-23 14:59:27 +00:00
str_format ( aCmd , sizeof ( aCmd ) , " set_team %d -1 %d " , SpectateID , g_Config . m_SvVoteSpectateRejoindelay ) ;
2013-12-26 17:02:22 +00:00
}
2014-08-12 11:41:57 +00:00
m_VoteKick = false ;
m_VoteSpec = true ;
2010-05-29 07:25:38 +00:00
}
2013-03-23 14:59:27 +00:00
2016-01-19 13:58:52 +00:00
if ( aCmd [ 0 ] & & str_comp ( aCmd , " info " ) ! = 0 )
2016-01-19 13:59:16 +00:00
CallVote ( ClientID , aDesc , aCmd , aReason , aChatmsg ) ;
2013-03-23 14:59:27 +00:00
}
else if ( MsgID = = NETMSGTYPE_CL_VOTE )
{
if ( ! m_VoteCloseTime )
2010-06-02 02:42:17 +00:00
return ;
2011-04-13 18:37:12 +00:00
2014-05-19 00:17:18 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastVoteTry & & pPlayer - > m_LastVoteTry + Server ( ) - > TickSpeed ( ) * 3 > Server ( ) - > Tick ( ) )
return ;
2011-04-09 06:41:31 +00:00
2014-05-19 00:17:18 +00:00
int64 Now = Server ( ) - > Tick ( ) ;
pPlayer - > m_LastVoteTry = Now ;
CNetMsg_Cl_Vote * pMsg = ( CNetMsg_Cl_Vote * ) pRawMsg ;
if ( ! pMsg - > m_Vote )
return ;
pPlayer - > m_Vote = pMsg - > m_Vote ;
pPlayer - > m_VotePos = + + m_VotePos ;
m_VoteUpdate = true ;
2010-05-29 07:25:38 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( MsgID = = NETMSGTYPE_CL_SETTEAM & & ! m_World . m_Paused )
2011-03-26 15:56:59 +00:00
{
2013-03-23 14:59:27 +00:00
CNetMsg_Cl_SetTeam * pMsg = ( CNetMsg_Cl_SetTeam * ) pRawMsg ;
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
//if(pPlayer->GetTeam() == pMsg->m_Team || (g_Config.m_SvSpamprotection && pPlayer->m_LastSetTeam && pPlayer->m_LastSetTeam+Server()->TickSpeed()*3 > Server()->Tick()))
if ( pPlayer - > GetTeam ( ) = = pMsg - > m_Team | | ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastSetTeam & & pPlayer - > m_LastSetTeam + Server ( ) - > TickSpeed ( ) * g_Config . m_SvTeamChangeDelay > Server ( ) - > Tick ( ) ) )
2011-03-26 15:56:59 +00:00
return ;
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
/*if(pMsg->m_Team != TEAM_SPECTATORS && m_LockTeams)
2011-03-26 15:56:59 +00:00
{
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastSetTeam = Server ( ) - > Tick ( ) ;
SendBroadcast ( " Teams are locked " , ClientID ) ;
2011-03-26 15:56:59 +00:00
return ;
2013-12-26 17:02:22 +00:00
} */
2011-04-13 18:37:12 +00:00
2014-09-22 14:12:01 +00:00
//Kill Protection
2017-03-21 10:24:44 +00:00
CCharacter * pChr = pPlayer - > GetCharacter ( ) ;
2014-09-22 16:57:56 +00:00
if ( pChr )
{
2014-09-22 14:12:01 +00:00
int CurrTime = ( Server ( ) - > Tick ( ) - pChr - > m_StartTime ) / Server ( ) - > TickSpeed ( ) ;
if ( g_Config . m_SvKillProtection ! = 0 & & CurrTime > = ( 60 * g_Config . m_SvKillProtection ) & & pChr - > m_DDRaceState = = DDRACE_STARTED )
{
2014-09-22 16:57:56 +00:00
SendChatTarget ( ClientID , " Kill Protection enabled. If you really want to join the spectators, first type /kill " ) ;
2014-09-22 14:12:01 +00:00
return ;
}
}
2013-03-23 14:59:27 +00:00
if ( pPlayer - > m_TeamChangeTick > Server ( ) - > Tick ( ) )
2013-07-11 00:54:54 +00:00
{
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastSetTeam = Server ( ) - > Tick ( ) ;
int TimeLeft = ( pPlayer - > m_TeamChangeTick - Server ( ) - > Tick ( ) ) / Server ( ) - > TickSpeed ( ) ;
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " Time to wait before changing team: %02d:%02d " , TimeLeft / 60 , TimeLeft % 60 ) ;
SendBroadcast ( aBuf , ClientID ) ;
2013-07-11 00:54:54 +00:00
return ;
}
2013-03-23 14:59:27 +00:00
// Switch team on given client and kill/respawn him
if ( m_pController - > CanJoinTeam ( pMsg - > m_Team , ClientID ) )
2011-06-06 20:18:37 +00:00
{
2013-12-26 17:02:22 +00:00
//if(m_pController->CanChangeTeam(pPlayer, pMsg->m_Team))
2017-04-08 22:20:41 +00:00
if ( pPlayer - > IsPaused ( ) )
2013-12-26 17:02:22 +00:00
SendChatTarget ( ClientID , " Use /pause first then you can kill " ) ;
else
2013-03-23 14:59:27 +00:00
{
2013-12-26 17:02:22 +00:00
//pPlayer->m_LastSetTeam = Server()->Tick();
2013-03-23 14:59:27 +00:00
if ( pPlayer - > GetTeam ( ) = = TEAM_SPECTATORS | | pMsg - > m_Team = = TEAM_SPECTATORS )
m_VoteUpdate = true ;
pPlayer - > SetTeam ( pMsg - > m_Team ) ;
2013-12-26 17:02:22 +00:00
//(void)m_pController->CheckTeamBalance();
2013-03-23 14:59:27 +00:00
pPlayer - > m_TeamChangeTick = Server ( ) - > Tick ( ) ;
}
2013-12-26 17:02:22 +00:00
//else
//SendBroadcast("Teams must be balanced, please join other team", ClientID);
2011-06-06 20:18:37 +00:00
}
else
{
2013-03-23 14:59:27 +00:00
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " Only %d active players are allowed " , Server ( ) - > MaxClients ( ) - g_Config . m_SvSpectatorSlots ) ;
SendBroadcast ( aBuf , ClientID ) ;
2011-08-13 00:11:06 +00:00
}
2011-03-26 15:56:59 +00:00
}
2014-01-30 15:49:15 +00:00
else if ( MsgID = = NETMSGTYPE_CL_ISDDNET )
2010-05-29 07:25:38 +00:00
{
2014-01-30 15:49:15 +00:00
int Version = pUnpacker - > GetInt ( ) ;
if ( pUnpacker - > Error ( ) )
{
if ( pPlayer - > m_ClientVersion < VERSION_DDRACE )
pPlayer - > m_ClientVersion = VERSION_DDRACE ;
2014-04-13 23:34:50 +00:00
}
2014-08-22 11:54:13 +00:00
else if ( pPlayer - > m_ClientVersion < Version )
2014-01-30 15:49:15 +00:00
pPlayer - > m_ClientVersion = Version ;
2017-04-22 17:04:16 +00:00
2017-01-04 13:14:10 +00:00
if ( pPlayer - > m_ClientVersion > = VERSION_DDNET_GAMETICK )
pPlayer - > m_TimerType = g_Config . m_SvDefaultTimerType ;
2017-04-22 17:04:16 +00:00
2016-05-02 19:35:32 +00:00
dbg_msg ( " ddnet " , " %d using Custom Client %d " , ClientID , pPlayer - > m_ClientVersion ) ;
2010-05-29 07:25:38 +00:00
2013-12-26 17:02:22 +00:00
//first update his teams state
2014-01-21 23:35:02 +00:00
( ( CGameControllerDDRace * ) m_pController ) - > m_Teams . SendTeamsState ( ClientID ) ;
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
//second give him records
SendRecord ( ClientID ) ;
2010-05-29 07:25:38 +00:00
2013-12-26 17:02:22 +00:00
//third give him others current time for table score
if ( g_Config . m_SvHideScore ) return ;
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] & & Score ( ) - > PlayerData ( i ) - > m_CurrentTime > 0 )
{
CNetMsg_Sv_PlayerTime Msg ;
Msg . m_Time = Score ( ) - > PlayerData ( i ) - > m_CurrentTime * 100 ;
Msg . m_ClientID = i ;
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
//also send its time to others
2011-05-23 11:06:38 +00:00
2013-12-26 17:02:22 +00:00
}
}
//also send its time to others
2014-04-13 23:34:50 +00:00
if ( Score ( ) - > PlayerData ( ClientID ) - > m_CurrentTime > 0 )
{
2013-12-26 17:02:22 +00:00
//TODO: make function for this fucking steps
CNetMsg_Sv_PlayerTime Msg ;
Msg . m_Time = Score ( ) - > PlayerData ( ClientID ) - > m_CurrentTime * 100 ;
Msg . m_ClientID = ClientID ;
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , - 1 ) ;
}
2014-04-13 23:34:50 +00:00
//and give him correct tunings
if ( Version > = VERSION_DDNET_EXTRATUNES )
2014-04-18 12:36:18 +00:00
SendTuningParams ( ClientID , pPlayer - > m_TuneZone ) ;
2015-07-04 12:12:49 +00:00
//tell old clients to update
if ( Version < VERSION_DDNET_UPDATER_FIXED & & g_Config . m_SvClientSuggestionOld [ 0 ] ! = ' \0 ' )
SendBroadcast ( g_Config . m_SvClientSuggestionOld , ClientID ) ;
2015-07-12 22:02:57 +00:00
//tell known bot clients that they're botting and we know it
2015-07-12 22:18:59 +00:00
if ( ( ( Version > = 15 & & Version < 100 ) | | Version = = 502 ) & & g_Config . m_SvClientSuggestionBot [ 0 ] ! = ' \0 ' )
2015-07-12 22:02:57 +00:00
SendBroadcast ( g_Config . m_SvClientSuggestionBot , ClientID ) ;
2014-01-02 01:13:10 +00:00
}
2013-12-26 17:02:22 +00:00
else if ( MsgID = = NETMSGTYPE_CL_SHOWOTHERS )
2010-05-29 07:25:38 +00:00
{
2013-12-26 17:02:22 +00:00
if ( g_Config . m_SvShowOthers & & ! g_Config . m_SvShowOthersDefault )
2011-01-29 00:59:50 +00:00
{
2013-12-26 17:02:22 +00:00
CNetMsg_Cl_ShowOthers * pMsg = ( CNetMsg_Cl_ShowOthers * ) pRawMsg ;
pPlayer - > m_ShowOthers = ( bool ) pMsg - > m_Show ;
2011-01-29 00:59:50 +00:00
}
2010-05-29 07:25:38 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( MsgID = = NETMSGTYPE_CL_SETSPECTATORMODE & & ! m_World . m_Paused )
2010-05-29 07:25:38 +00:00
{
2013-03-23 14:59:27 +00:00
CNetMsg_Cl_SetSpectatorMode * pMsg = ( CNetMsg_Cl_SetSpectatorMode * ) pRawMsg ;
2011-04-09 06:41:31 +00:00
2013-12-31 17:25:40 +00:00
if ( pMsg - > m_SpectatorID ! = SPEC_FREEVIEW )
if ( ! Server ( ) - > ReverseTranslate ( pMsg - > m_SpectatorID , ClientID ) )
return ;
2014-10-03 19:41:18 +00:00
if ( ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastSetSpectatorMode & & pPlayer - > m_LastSetSpectatorMode + Server ( ) - > TickSpeed ( ) / 4 > Server ( ) - > Tick ( ) ) )
2010-05-29 07:25:38 +00:00
return ;
2011-04-09 06:41:31 +00:00
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastSetSpectatorMode = Server ( ) - > Tick ( ) ;
if ( pMsg - > m_SpectatorID ! = SPEC_FREEVIEW & & ( ! m_apPlayers [ pMsg - > m_SpectatorID ] | | m_apPlayers [ pMsg - > m_SpectatorID ] - > GetTeam ( ) = = TEAM_SPECTATORS ) )
SendChatTarget ( ClientID , " Invalid spectator id used " ) ;
else
pPlayer - > m_SpectatorID = pMsg - > m_SpectatorID ;
2008-09-25 12:23:44 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( MsgID = = NETMSGTYPE_CL_CHANGEINFO )
2012-01-08 12:55:20 +00:00
{
2013-12-26 17:02:22 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastChangeInfo & & pPlayer - > m_LastChangeInfo + Server ( ) - > TickSpeed ( ) * g_Config . m_SvInfoChangeDelay > Server ( ) - > Tick ( ) )
2013-03-23 14:59:27 +00:00
return ;
2011-04-09 06:41:31 +00:00
2013-03-23 14:59:27 +00:00
CNetMsg_Cl_ChangeInfo * pMsg = ( CNetMsg_Cl_ChangeInfo * ) pRawMsg ;
2016-01-27 00:48:19 +00:00
if ( ! str_utf8_check ( pMsg - > m_pName )
| | ! str_utf8_check ( pMsg - > m_pClan )
| | ! str_utf8_check ( pMsg - > m_pSkin ) )
2016-01-27 00:24:02 +00:00
{
return ;
}
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastChangeInfo = Server ( ) - > Tick ( ) ;
2011-04-09 06:41:31 +00:00
2013-03-23 14:59:27 +00:00
// set infos
char aOldName [ MAX_NAME_LENGTH ] ;
str_copy ( aOldName , Server ( ) - > ClientName ( ClientID ) , sizeof ( aOldName ) ) ;
Server ( ) - > SetClientName ( ClientID , pMsg - > m_pName ) ;
if ( str_comp ( aOldName , Server ( ) - > ClientName ( ClientID ) ) ! = 0 )
2010-10-30 14:22:35 +00:00
{
2013-03-23 14:59:27 +00:00
char aChatText [ 256 ] ;
str_format ( aChatText , sizeof ( aChatText ) , " '%s' changed name to '%s' " , aOldName , Server ( ) - > ClientName ( ClientID ) ) ;
SendChat ( - 1 , CGameContext : : CHAT_ALL , aChatText ) ;
2013-12-26 17:02:22 +00:00
// reload scores
2011-04-09 06:41:31 +00:00
2013-12-26 17:02:22 +00:00
Score ( ) - > PlayerData ( ClientID ) - > Reset ( ) ;
Score ( ) - > LoadScore ( ClientID ) ;
Score ( ) - > PlayerData ( ClientID ) - > m_CurrentTime = Score ( ) - > PlayerData ( ClientID ) - > m_BestTime ;
m_apPlayers [ ClientID ] - > m_Score = ( Score ( ) - > PlayerData ( ClientID ) - > m_BestTime ) ? Score ( ) - > PlayerData ( ClientID ) - > m_BestTime : - 9999 ;
2010-10-30 14:22:35 +00:00
}
2013-03-23 14:59:27 +00:00
Server ( ) - > SetClientClan ( ClientID , pMsg - > m_pClan ) ;
Server ( ) - > SetClientCountry ( ClientID , pMsg - > m_Country ) ;
str_copy ( pPlayer - > m_TeeInfos . m_SkinName , pMsg - > m_pSkin , sizeof ( pPlayer - > m_TeeInfos . m_SkinName ) ) ;
pPlayer - > m_TeeInfos . m_UseCustomColor = pMsg - > m_UseCustomColor ;
pPlayer - > m_TeeInfos . m_ColorBody = pMsg - > m_ColorBody ;
pPlayer - > m_TeeInfos . m_ColorFeet = pMsg - > m_ColorFeet ;
2013-12-26 17:02:22 +00:00
//m_pController->OnPlayerInfoChange(pPlayer);
2010-10-30 14:22:35 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( MsgID = = NETMSGTYPE_CL_EMOTICON & & ! m_World . m_Paused )
2013-02-02 13:08:02 +00:00
{
2013-03-23 14:59:27 +00:00
CNetMsg_Cl_Emoticon * pMsg = ( CNetMsg_Cl_Emoticon * ) pRawMsg ;
2011-04-13 18:37:12 +00:00
2013-12-26 17:02:22 +00:00
if ( g_Config . m_SvSpamprotection & & pPlayer - > m_LastEmote & & pPlayer - > m_LastEmote + Server ( ) - > TickSpeed ( ) * g_Config . m_SvEmoticonDelay > Server ( ) - > Tick ( ) )
2013-03-23 14:59:27 +00:00
return ;
2010-05-29 07:25:38 +00:00
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastEmote = Server ( ) - > Tick ( ) ;
2011-03-15 08:58:57 +00:00
2013-03-23 14:59:27 +00:00
SendEmoticon ( ClientID , pMsg - > m_Emoticon ) ;
2017-03-21 10:24:44 +00:00
CCharacter * pChr = pPlayer - > GetCharacter ( ) ;
2013-12-26 17:02:22 +00:00
if ( pChr & & g_Config . m_SvEmotionalTees & & pPlayer - > m_EyeEmote )
2010-05-29 07:25:38 +00:00
{
2013-12-26 17:02:22 +00:00
switch ( pMsg - > m_Emoticon )
2011-03-26 21:06:29 +00:00
{
2013-12-26 17:02:22 +00:00
case EMOTICON_EXCLAMATION :
case EMOTICON_GHOST :
case EMOTICON_QUESTION :
case EMOTICON_WTF :
pChr - > SetEmoteType ( EMOTE_SURPRISE ) ;
break ;
case EMOTICON_DOTDOT :
case EMOTICON_DROP :
case EMOTICON_ZZZ :
pChr - > SetEmoteType ( EMOTE_BLINK ) ;
break ;
case EMOTICON_EYES :
case EMOTICON_HEARTS :
case EMOTICON_MUSIC :
pChr - > SetEmoteType ( EMOTE_HAPPY ) ;
break ;
case EMOTICON_OOP :
case EMOTICON_SORRY :
case EMOTICON_SUSHI :
pChr - > SetEmoteType ( EMOTE_PAIN ) ;
break ;
case EMOTICON_DEVILTEE :
case EMOTICON_SPLATTEE :
case EMOTICON_ZOMG :
pChr - > SetEmoteType ( EMOTE_ANGRY ) ;
break ;
default :
pChr - > SetEmoteType ( EMOTE_NORMAL ) ;
break ;
2011-03-26 21:06:29 +00:00
}
2013-12-26 17:02:22 +00:00
pChr - > SetEmoteStop ( Server ( ) - > Tick ( ) + 2 * Server ( ) - > TickSpeed ( ) ) ;
2010-05-29 07:25:38 +00:00
}
2011-03-26 21:06:29 +00:00
}
2013-03-23 14:59:27 +00:00
else if ( MsgID = = NETMSGTYPE_CL_KILL & & ! m_World . m_Paused )
2010-05-29 07:25:38 +00:00
{
2015-07-09 17:07:33 +00:00
if ( m_VoteCloseTime & & m_VoteCreator = = ClientID & & GetDDRaceTeam ( ClientID ) & & ( m_VoteKick | | m_VoteSpec ) )
2013-12-26 17:02:22 +00:00
{
SendChatTarget ( ClientID , " You are running a vote please try again after the vote is done! " ) ;
return ;
}
if ( pPlayer - > m_LastKill & & pPlayer - > m_LastKill + Server ( ) - > TickSpeed ( ) * g_Config . m_SvKillDelay > Server ( ) - > Tick ( ) )
return ;
2017-04-08 22:20:41 +00:00
if ( pPlayer - > IsPaused ( ) )
2013-03-23 14:59:27 +00:00
return ;
2011-06-07 15:05:07 +00:00
2017-03-21 10:24:44 +00:00
CCharacter * pChr = pPlayer - > GetCharacter ( ) ;
2014-08-25 09:35:55 +00:00
if ( ! pChr )
return ;
2014-08-24 21:24:33 +00:00
//Kill Protection
2014-08-25 09:35:55 +00:00
int CurrTime = ( Server ( ) - > Tick ( ) - pChr - > m_StartTime ) / Server ( ) - > TickSpeed ( ) ;
if ( g_Config . m_SvKillProtection ! = 0 & & CurrTime > = ( 60 * g_Config . m_SvKillProtection ) & & pChr - > m_DDRaceState = = DDRACE_STARTED )
2014-08-24 21:24:33 +00:00
{
2014-09-22 14:12:01 +00:00
SendChatTarget ( ClientID , " Kill Protection enabled. If you really want to kill, type /kill " ) ;
2014-08-24 21:24:33 +00:00
return ;
}
2013-03-23 14:59:27 +00:00
pPlayer - > m_LastKill = Server ( ) - > Tick ( ) ;
pPlayer - > KillCharacter ( WEAPON_SELF ) ;
2016-02-02 20:14:46 +00:00
pPlayer - > Respawn ( ) ;
2010-05-29 07:25:38 +00:00
}
}
2014-08-09 12:50:51 +00:00
if ( MsgID = = NETMSGTYPE_CL_STARTINFO )
2010-05-29 07:25:38 +00:00
{
2015-06-18 15:47:07 +00:00
if ( pPlayer - > m_IsReady )
2015-05-19 15:47:41 +00:00
return ;
2014-08-09 12:50:51 +00:00
CNetMsg_Cl_StartInfo * pMsg = ( CNetMsg_Cl_StartInfo * ) pRawMsg ;
2016-01-27 00:48:19 +00:00
if ( ! str_utf8_check ( pMsg - > m_pName )
| | ! str_utf8_check ( pMsg - > m_pClan )
| | ! str_utf8_check ( pMsg - > m_pSkin ) )
2016-01-27 00:24:02 +00:00
{
return ;
}
2014-08-09 12:50:51 +00:00
pPlayer - > m_LastChangeInfo = Server ( ) - > Tick ( ) ;
// set start infos
Server ( ) - > SetClientName ( ClientID , pMsg - > m_pName ) ;
Server ( ) - > SetClientClan ( ClientID , pMsg - > m_pClan ) ;
Server ( ) - > SetClientCountry ( ClientID , pMsg - > m_Country ) ;
str_copy ( pPlayer - > m_TeeInfos . m_SkinName , pMsg - > m_pSkin , sizeof ( pPlayer - > m_TeeInfos . m_SkinName ) ) ;
pPlayer - > m_TeeInfos . m_UseCustomColor = pMsg - > m_UseCustomColor ;
pPlayer - > m_TeeInfos . m_ColorBody = pMsg - > m_ColorBody ;
pPlayer - > m_TeeInfos . m_ColorFeet = pMsg - > m_ColorFeet ;
//m_pController->OnPlayerInfoChange(pPlayer);
2014-10-26 18:39:42 +00:00
// send clear vote options
2014-08-09 12:50:51 +00:00
CNetMsg_Sv_VoteClearOptions ClearMsg ;
Server ( ) - > SendPackMsg ( & ClearMsg , MSGFLAG_VITAL , ClientID ) ;
2014-10-26 18:39:42 +00:00
// begin sending vote options
pPlayer - > m_SendVoteIndex = 0 ;
2011-04-13 18:37:12 +00:00
2014-08-09 12:50:51 +00:00
// send tuning parameters to client
SendTuningParams ( ClientID , pPlayer - > m_TuneZone ) ;
2011-04-13 18:37:12 +00:00
2014-08-09 12:50:51 +00:00
// client is ready to enter
if ( ! pPlayer - > m_IsReady )
{
2013-03-23 14:59:27 +00:00
pPlayer - > m_IsReady = true ;
CNetMsg_Sv_ReadyToEnter m ;
Server ( ) - > SendPackMsg ( & m , MSGFLAG_VITAL | MSGFLAG_FLUSH , ClientID ) ;
}
2010-05-29 07:25:38 +00:00
}
}
2011-01-29 00:59:50 +00:00
2011-08-13 00:11:06 +00:00
void CGameContext : : ConTuneParam ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
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 ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
2010-05-29 07:25:38 +00:00
pSelf - > SendTuningParams ( - 1 ) ;
}
else
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " No such tuning parameter " ) ;
2010-05-29 07:25:38 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConTuneReset ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-08-13 00:11:06 +00:00
/*CTuningParams TuningParams;
* pSelf - > Tuning ( ) = TuningParams ;
pSelf - > SendTuningParams ( - 1 ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " Tuning reset " ) ; */
2011-05-30 20:05:28 +00:00
pSelf - > ResetTuning ( ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " Tuning reset " ) ;
2010-05-29 07:25:38 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConTuneDump ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
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 + + )
{
float v ;
pSelf - > Tuning ( ) - > Get ( i , & v ) ;
2017-03-21 10:24:44 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %s %.2f " , pSelf - > Tuning ( ) - > ms_apNames [ i ] , v ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
}
2014-03-12 23:31:50 +00:00
void CGameContext : : ConTuneZone ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
int List = pResult - > GetInteger ( 0 ) ;
const char * pParamName = pResult - > GetString ( 1 ) ;
float NewValue = pResult - > GetFloat ( 2 ) ;
2015-07-09 00:08:14 +00:00
2017-07-26 01:58:00 +00:00
if ( List > = 0 & & List < NUM_TUNEZONES )
2014-03-12 23:31:50 +00:00
{
2014-03-23 17:56:07 +00:00
if ( pSelf - > TuningList ( ) [ List ] . Set ( pParamName , NewValue ) )
2014-03-12 23:31:50 +00:00
{
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %s in zone %d changed to %.2f " , pParamName , List , NewValue ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
2014-03-29 13:54:43 +00:00
pSelf - > SendTuningParams ( - 1 , List ) ;
2014-03-12 23:31:50 +00:00
}
else
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " No such tuning parameter " ) ;
}
}
void CGameContext : : ConTuneDumpZone ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
int List = pResult - > GetInteger ( 0 ) ;
char aBuf [ 256 ] ;
2017-07-26 01:58:00 +00:00
if ( List > = 0 & & List < NUM_TUNEZONES )
2014-03-12 23:31:50 +00:00
{
2014-03-23 17:56:07 +00:00
for ( int i = 0 ; i < pSelf - > TuningList ( ) [ List ] . Num ( ) ; i + + )
{
float v ;
pSelf - > TuningList ( ) [ List ] . Get ( i , & v ) ;
2017-03-21 10:24:44 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " zone %d: %s %.2f " , List , pSelf - > TuningList ( ) [ List ] . ms_apNames [ i ] , v ) ;
2014-03-23 17:56:07 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
}
2014-03-12 23:31:50 +00:00
}
}
void CGameContext : : ConTuneResetZone ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
CTuningParams TuningParams ;
if ( pResult - > NumArguments ( ) )
{
int List = pResult - > GetInteger ( 0 ) ;
2017-07-26 01:58:00 +00:00
if ( List > = 0 & & List < NUM_TUNEZONES )
2014-03-12 23:31:50 +00:00
{
2014-03-23 17:56:07 +00:00
pSelf - > TuningList ( ) [ List ] = TuningParams ;
2014-03-12 23:31:50 +00:00
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " Tunezone %d resetted " , List ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , aBuf ) ;
2014-03-29 13:54:43 +00:00
pSelf - > SendTuningParams ( - 1 , List ) ;
2014-03-12 23:31:50 +00:00
}
}
else
{
2017-07-26 01:58:00 +00:00
for ( int i = 0 ; i < NUM_TUNEZONES ; i + + )
2014-03-29 13:54:43 +00:00
{
2014-03-12 23:31:50 +00:00
* ( pSelf - > TuningList ( ) + i ) = TuningParams ;
2014-03-29 13:54:43 +00:00
pSelf - > SendTuningParams ( - 1 , i ) ;
}
2014-03-12 23:31:50 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " tuning " , " All Tunezones resetted " ) ;
}
}
void CGameContext : : ConTuneSetZoneMsgEnter ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
if ( pResult - > NumArguments ( ) )
{
int List = pResult - > GetInteger ( 0 ) ;
2017-07-26 01:58:00 +00:00
if ( List > = 0 & & List < NUM_TUNEZONES )
2014-03-12 23:31:50 +00:00
{
2017-07-26 01:58:00 +00:00
str_copy ( pSelf - > m_aaZoneEnterMsg [ List ] , pResult - > GetString ( 1 ) , sizeof ( pSelf - > m_aaZoneEnterMsg [ List ] ) ) ;
2014-03-12 23:31:50 +00:00
}
}
}
void CGameContext : : ConTuneSetZoneMsgLeave ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
if ( pResult - > NumArguments ( ) )
{
int List = pResult - > GetInteger ( 0 ) ;
2017-07-26 01:58:00 +00:00
if ( List > = 0 & & List < NUM_TUNEZONES )
2014-03-12 23:31:50 +00:00
{
2017-07-26 01:58:00 +00:00
str_copy ( pSelf - > m_aaZoneLeaveMsg [ List ] , pResult - > GetString ( 1 ) , sizeof ( pSelf - > m_aaZoneLeaveMsg [ List ] ) ) ;
2014-03-12 23:31:50 +00:00
}
}
}
2015-07-22 21:31:50 +00:00
void CGameContext : : ConSwitchOpen ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
int Switch = pResult - > GetInteger ( 0 ) ;
if ( pSelf - > Collision ( ) - > m_NumSwitchers > 0 & & Switch > = 0 & & Switch < pSelf - > Collision ( ) - > m_NumSwitchers + 1 )
{
pSelf - > Collision ( ) - > m_pSwitchers [ Switch ] . m_Initial = false ;
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " switch %d opened by default " , Switch ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
}
}
2012-01-09 23:49:31 +00:00
void CGameContext : : ConPause ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2012-04-12 00:09:31 +00:00
/*if(pSelf->m_pController->IsGameOver())
return ; */
2012-01-09 23:49:31 +00:00
pSelf - > m_World . m_Paused ^ = 1 ;
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConChangeMap ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
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
}
2013-12-06 23:15:56 +00:00
void CGameContext : : ConRandomMap ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2014-10-10 22:41:56 +00:00
2014-10-10 23:01:32 +00:00
int stars = 0 ;
2014-10-10 22:41:56 +00:00
if ( pResult - > NumArguments ( ) )
stars = pResult - > GetInteger ( 0 ) ;
2013-12-06 23:15:56 +00:00
2014-10-10 23:01:32 +00:00
pSelf - > m_pScore - > RandomMap ( pSelf - > m_VoteCreator , stars ) ;
2013-12-06 23:15:56 +00:00
}
2014-06-20 20:40:23 +00:00
void CGameContext : : ConRandomUnfinishedMap ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2014-10-10 22:41:56 +00:00
int stars = 0 ;
if ( pResult - > NumArguments ( ) )
stars = pResult - > GetInteger ( 0 ) ;
pSelf - > m_pScore - > RandomUnfinishedMap ( pSelf - > m_VoteCreator , stars ) ;
2014-06-20 20:40:23 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConRestart ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
if ( pResult - > NumArguments ( ) )
pSelf - > m_pController - > DoWarmup ( pResult - > GetInteger ( 0 ) ) ;
else
pSelf - > m_pController - > StartRound ( ) ;
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConBroadcast ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2014-04-18 22:40:21 +00:00
char aBuf [ 1024 ] ;
str_copy ( aBuf , pResult - > GetString ( 0 ) , sizeof ( aBuf ) ) ;
int i , j ;
for ( i = 0 , j = 0 ; aBuf [ i ] ; i + + , j + + )
{
if ( aBuf [ i ] = = ' \\ ' & & aBuf [ i + 1 ] = = ' n ' )
{
aBuf [ j ] = ' \n ' ;
i + + ;
}
else if ( i ! = j )
{
aBuf [ j ] = aBuf [ i ] ;
}
}
aBuf [ j ] = ' \0 ' ;
pSelf - > SendBroadcast ( aBuf , - 1 ) ;
2010-05-29 07:25:38 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConSay ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
pSelf - > SendChat ( - 1 , CGameContext : : CHAT_ALL , pResult - > GetString ( 0 ) ) ;
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConSetTeam ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
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 ) ;
2011-12-30 21:47:26 +00:00
int Delay = pResult - > NumArguments ( ) > 2 ? pResult - > GetInteger ( 2 ) : 0 ;
if ( ! pSelf - > m_apPlayers [ ClientID ] )
return ;
2011-04-13 18:37:12 +00:00
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-11-21 22:25:30 +00:00
2011-05-25 10:05:32 +00:00
pSelf - > m_apPlayers [ ClientID ] - > m_TeamChangeTick = pSelf - > Server ( ) - > Tick ( ) + pSelf - > Server ( ) - > TickSpeed ( ) * Delay * 60 ;
2011-02-12 10:40:36 +00:00
pSelf - > m_apPlayers [ ClientID ] - > SetTeam ( Team ) ;
2013-07-28 21:43:27 +00:00
if ( Team = = TEAM_SPECTATORS )
2017-04-08 23:16:48 +00:00
pSelf - > m_apPlayers [ ClientID ] - > Pause ( CPlayer : : PAUSE_NONE , true ) ;
2011-08-13 00:11:06 +00:00
// (void)pSelf->m_pController->CheckTeamBalance();
2010-05-29 07:25:38 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConSetTeamAll ( IConsole : : IResult * pResult , void * pUserData )
2011-01-06 12:37:28 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
int Team = clamp ( pResult - > GetInteger ( 0 ) , - 1 , 1 ) ;
2011-04-13 18:37:12 +00:00
2011-01-06 12:37:28 +00:00
char aBuf [ 256 ] ;
2011-12-30 21:30:28 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " All players were moved to the %s " , pSelf - > m_pController - > GetTeamName ( Team ) ) ;
pSelf - > SendChat ( - 1 , CGameContext : : CHAT_ALL , aBuf ) ;
2011-04-13 18:37:12 +00:00
2011-01-06 12:37:28 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
if ( pSelf - > m_apPlayers [ i ] )
2011-12-30 21:30:28 +00:00
pSelf - > m_apPlayers [ i ] - > SetTeam ( Team , false ) ;
2011-04-13 18:37:12 +00:00
2011-08-13 00:11:06 +00:00
// (void)pSelf->m_pController->CheckTeamBalance();
2011-01-06 12:37:28 +00:00
}
2011-12-31 22:00:00 +00:00
/*
2011-09-04 09:13:30 +00:00
void CGameContext : : ConSwapTeams ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-12-30 21:47:26 +00:00
pSelf - > SwapTeams ( ) ;
2011-09-04 09:13:30 +00:00
}
2011-01-06 12:37:28 +00:00
2011-09-04 09:13:30 +00:00
void CGameContext : : ConShuffleTeams ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-12-30 21:17:51 +00:00
if ( ! pSelf - > m_pController - > IsTeamplay ( ) )
return ;
2011-09-04 09:13:30 +00:00
2011-12-30 21:17:51 +00:00
int CounterRed = 0 ;
int CounterBlue = 0 ;
int PlayerTeam = 0 ;
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
if ( pSelf - > m_apPlayers [ i ] & & pSelf - > m_apPlayers [ i ] - > GetTeam ( ) ! = TEAM_SPECTATORS )
+ + PlayerTeam ;
PlayerTeam = ( PlayerTeam + 1 ) / 2 ;
2015-07-09 00:08:14 +00:00
2011-12-30 21:30:28 +00:00
pSelf - > SendChat ( - 1 , CGameContext : : CHAT_ALL , " Teams were shuffled " ) ;
2011-09-04 09:13:30 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; + + i )
{
if ( pSelf - > m_apPlayers [ i ] & & pSelf - > m_apPlayers [ i ] - > GetTeam ( ) ! = TEAM_SPECTATORS )
{
2011-12-30 21:17:51 +00:00
if ( CounterRed = = PlayerTeam )
2011-12-30 21:30:28 +00:00
pSelf - > m_apPlayers [ i ] - > SetTeam ( TEAM_BLUE , false ) ;
2011-12-30 21:17:51 +00:00
else if ( CounterBlue = = PlayerTeam )
2011-12-30 21:30:28 +00:00
pSelf - > m_apPlayers [ i ] - > SetTeam ( TEAM_RED , false ) ;
2011-09-04 09:13:30 +00:00
else
2015-07-09 00:08:14 +00:00
{
2011-09-04 09:13:30 +00:00
if ( rand ( ) % 2 )
{
2011-12-30 21:30:28 +00:00
pSelf - > m_apPlayers [ i ] - > SetTeam ( TEAM_BLUE , false ) ;
2011-12-30 21:17:51 +00:00
+ + CounterBlue ;
2011-09-04 09:13:30 +00:00
}
else
{
2011-12-30 21:30:28 +00:00
pSelf - > m_apPlayers [ i ] - > SetTeam ( TEAM_RED , false ) ;
2011-12-30 21:17:51 +00:00
+ + CounterRed ;
2011-09-04 09:13:30 +00:00
}
}
}
}
2011-12-30 21:17:51 +00:00
2011-12-31 22:00:00 +00:00
// (void)pSelf->m_pController->CheckTeamBalance();
2011-09-04 09:13:30 +00:00
}
2012-01-08 12:55:20 +00:00
void CGameContext : : ConLockTeams ( IConsole : : IResult * pResult , void * pUserData )
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
pSelf - > m_LockTeams ^ = 1 ;
if ( pSelf - > m_LockTeams )
pSelf - > SendChat ( - 1 , CGameContext : : CHAT_ALL , " Teams were locked " ) ;
else
pSelf - > SendChat ( - 1 , CGameContext : : CHAT_ALL , " Teams were unlocked " ) ;
}
2011-12-31 22:00:00 +00:00
*/
2011-08-13 00:11:06 +00:00
void CGameContext : : ConAddVote ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-03-25 08:49:21 +00:00
const char * pDescription = pResult - > GetString ( 0 ) ;
const char * pCommand = pResult - > GetString ( 1 ) ;
2011-03-26 21:06:29 +00:00
if ( pSelf - > m_NumVoteOptions = = MAX_VOTE_OPTIONS )
{
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " maximum number of vote options reached " ) ;
2011-03-26 21:06:29 +00:00
return ;
}
2011-04-13 18:37:12 +00:00
2010-10-25 16:30:35 +00:00
// check for valid option
2011-04-10 13:32:56 +00:00
if ( ! pSelf - > Console ( ) - > LineIsValid ( pCommand ) | | str_length ( pCommand ) > = VOTE_CMD_LENGTH )
2010-10-25 16:30:35 +00:00
{
char aBuf [ 256 ] ;
2011-03-26 16:44:34 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " skipped invalid command '%s' " , pCommand ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2011-03-26 16:44:34 +00:00
return ;
}
2011-04-05 18:06:41 +00:00
while ( * pDescription & & * pDescription = = ' ' )
pDescription + + ;
if ( str_length ( pDescription ) > = VOTE_DESC_LENGTH | | * pDescription = = 0 )
2011-03-26 16:44:34 +00:00
{
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " skipped invalid option '%s' " , pDescription ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-10-25 16:30:35 +00:00
return ;
}
2011-04-13 18:37:12 +00:00
2011-03-25 08:49:21 +00:00
// check for duplicate entry
2011-03-26 16:44:34 +00:00
CVoteOptionServer * pOption = pSelf - > m_pVoteOptionFirst ;
2010-11-20 18:30:52 +00:00
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 ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-11-20 18:30:52 +00:00
return ;
}
pOption = pOption - > m_pNext ;
}
2011-04-13 18:37:12 +00:00
2011-03-25 08:49:21 +00:00
// add the option
2011-03-26 21:06:29 +00:00
+ + pSelf - > m_NumVoteOptions ;
2011-03-25 08:49:21 +00:00
int Len = str_length ( pCommand ) ;
2011-04-13 18:37:12 +00:00
2011-03-26 16:44:34 +00:00
pOption = ( CVoteOptionServer * ) pSelf - > m_pVoteOptionHeap - > Allocate ( sizeof ( CVoteOptionServer ) + 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-04-13 18:37:12 +00:00
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 ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConRemoveVote ( IConsole : : IResult * pResult , void * pUserData )
2011-03-25 10:49:35 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
const char * pDescription = pResult - > GetString ( 0 ) ;
2011-04-13 18:37:12 +00:00
2011-03-25 10:49:35 +00:00
// check for valid option
2011-03-26 16:44:34 +00:00
CVoteOptionServer * pOption = pSelf - > m_pVoteOptionFirst ;
2011-03-25 10:49:35 +00:00
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 ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2011-03-25 10:49:35 +00:00
return ;
}
2011-04-04 14:58:53 +00:00
2014-10-27 12:34:29 +00:00
// start reloading vote option list
// clear vote options
CNetMsg_Sv_VoteClearOptions VoteClearOptionsMsg ;
pSelf - > Server ( ) - > SendPackMsg ( & VoteClearOptionsMsg , MSGFLAG_VITAL , - 1 ) ;
// reset sending of vote options
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( pSelf - > m_apPlayers [ i ] )
pSelf - > m_apPlayers [ i ] - > m_SendVoteIndex = 0 ;
}
2011-04-13 18:37:12 +00:00
2011-03-25 10:49:35 +00:00
// TODO: improve this
// remove the option
2011-03-26 21:06:29 +00:00
- - pSelf - > m_NumVoteOptions ;
2011-03-25 10:49:35 +00:00
char aBuf [ 256 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " removed option '%s' '%s' " , pOption - > m_aDescription , pOption - > m_aCommand ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2011-03-25 10:49:35 +00:00
2011-03-25 11:06:45 +00:00
CHeap * pVoteOptionHeap = new CHeap ( ) ;
2011-03-26 16:44:34 +00:00
CVoteOptionServer * pVoteOptionFirst = 0 ;
CVoteOptionServer * pVoteOptionLast = 0 ;
2011-03-26 21:06:29 +00:00
int NumVoteOptions = pSelf - > m_NumVoteOptions ;
2011-03-26 16:44:34 +00:00
for ( CVoteOptionServer * pSrc = pSelf - > m_pVoteOptionFirst ; pSrc ; pSrc = pSrc - > m_pNext )
2011-03-25 10:49:35 +00:00
{
if ( pSrc = = pOption )
continue ;
// copy option
int Len = str_length ( pSrc - > m_aCommand ) ;
2011-03-26 16:44:34 +00:00
CVoteOptionServer * pDst = ( CVoteOptionServer * ) pVoteOptionHeap - > Allocate ( sizeof ( CVoteOptionServer ) + Len ) ;
2011-03-25 10:49:35 +00:00
pDst - > m_pNext = 0 ;
pDst - > m_pPrev = pVoteOptionLast ;
if ( pDst - > m_pPrev )
pDst - > m_pPrev - > m_pNext = pDst ;
pVoteOptionLast = pDst ;
if ( ! pVoteOptionFirst )
pVoteOptionFirst = pDst ;
2011-04-13 18:37:12 +00:00
2011-03-25 10:49:35 +00:00
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 ;
2011-03-26 21:06:29 +00:00
pSelf - > m_NumVoteOptions = NumVoteOptions ;
2010-05-29 07:25:38 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConForceVote ( IConsole : : IResult * pResult , void * pUserData )
2011-03-25 11:06:45 +00:00
{
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 )
{
2011-03-26 16:44:34 +00:00
CVoteOptionServer * pOption = pSelf - > m_pVoteOptionFirst ;
2011-03-25 11:06:45 +00:00
while ( pOption )
{
if ( str_comp_nocase ( pValue , pOption - > m_aDescription ) = = 0 )
{
2014-09-06 19:19:44 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " moderator forced server option '%s' (%s) " , pValue , pReason ) ;
2011-03-25 11:06:45 +00:00
pSelf - > SendChatTarget ( - 1 , aBuf ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > ExecuteLine ( pOption - > m_aCommand ) ;
2011-03-25 11:06:45 +00:00
break ;
}
pOption = pOption - > m_pNext ;
}
2011-04-13 18:37:12 +00:00
2011-03-25 11:06:45 +00:00
if ( ! pOption )
{
str_format ( aBuf , sizeof ( aBuf ) , " '%s' isn't an option on this server " , pValue ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , aBuf ) ;
2011-03-25 11:06:45 +00:00
return ;
}
}
else if ( str_comp_nocase ( pType , " kick " ) = = 0 )
{
int KickID = str_toint ( pValue ) ;
if ( KickID < 0 | | KickID > = MAX_CLIENTS | | ! pSelf - > m_apPlayers [ KickID ] )
{
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " Invalid client id to kick " ) ;
2011-03-25 11:06:45 +00:00
return ;
}
if ( ! g_Config . m_SvVoteKickBantime )
{
str_format ( aBuf , sizeof ( aBuf ) , " kick %d %s " , KickID , pReason ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > ExecuteLine ( aBuf ) ;
2011-03-25 11:06:45 +00:00
}
else
{
2011-03-28 18:11:28 +00:00
char aAddrStr [ NETADDR_MAXSTRSIZE ] = { 0 } ;
pSelf - > Server ( ) - > GetClientAddr ( KickID , aAddrStr , sizeof ( aAddrStr ) ) ;
str_format ( aBuf , sizeof ( aBuf ) , " ban %s %d %s " , aAddrStr , g_Config . m_SvVoteKickBantime , pReason ) ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > ExecuteLine ( aBuf ) ;
2011-03-25 11:06:45 +00:00
}
}
2011-03-26 15:56:59 +00:00
else if ( str_comp_nocase ( pType , " spectate " ) = = 0 )
{
int SpectateID = str_toint ( pValue ) ;
if ( SpectateID < 0 | | SpectateID > = MAX_CLIENTS | | ! pSelf - > m_apPlayers [ SpectateID ] | | pSelf - > m_apPlayers [ SpectateID ] - > GetTeam ( ) = = TEAM_SPECTATORS )
{
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " Invalid client id to move " ) ;
2011-03-26 15:56:59 +00:00
return ;
}
2011-04-13 18:37:12 +00:00
2011-07-10 11:02:13 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " admin moved '%s' to spectator (%s) " , pSelf - > Server ( ) - > ClientName ( SpectateID ) , pReason ) ;
pSelf - > SendChatTarget ( - 1 , aBuf ) ;
2011-05-25 10:05:32 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " set_team %d -1 %d " , SpectateID , g_Config . m_SvVoteSpectateRejoindelay ) ;
2011-03-26 15:56:59 +00:00
pSelf - > Console ( ) - > ExecuteLine ( aBuf ) ;
}
2011-03-25 11:06:45 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConClearVotes ( IConsole : : IResult * pResult , void * pUserData )
2011-01-21 19:46:00 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2011-08-13 00:11:06 +00:00
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " server " , " cleared votes " ) ;
2011-01-21 19:46:00 +00:00
CNetMsg_Sv_VoteClearOptions VoteClearOptionsMsg ;
pSelf - > Server ( ) - > SendPackMsg ( & VoteClearOptionsMsg , MSGFLAG_VITAL , - 1 ) ;
pSelf - > m_pVoteOptionHeap - > Reset ( ) ;
pSelf - > m_pVoteOptionFirst = 0 ;
pSelf - > m_pVoteOptionLast = 0 ;
2011-03-26 21:06:29 +00:00
pSelf - > m_NumVoteOptions = 0 ;
2014-10-26 18:39:42 +00:00
// reset sending of vote options
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( pSelf - > m_apPlayers [ i ] )
pSelf - > m_apPlayers [ i ] - > m_SendVoteIndex = 0 ;
}
2011-01-21 19:46:00 +00:00
}
2011-08-13 00:11:06 +00:00
void CGameContext : : ConVote ( IConsole : : IResult * pResult , void * pUserData )
2010-05-29 07:25:38 +00:00
{
CGameContext * pSelf = ( CGameContext * ) pUserData ;
2012-01-26 21:17:26 +00:00
// check if there is a vote running
if ( ! pSelf - > m_VoteCloseTime )
return ;
2010-05-29 07:25:38 +00:00
if ( str_comp_nocase ( pResult - > GetString ( 0 ) , " yes " ) = = 0 )
2011-11-08 11:06:09 +00:00
pSelf - > m_VoteEnforce = CGameContext : : VOTE_ENFORCE_YES_ADMIN ;
2010-05-29 07:25:38 +00:00
else if ( str_comp_nocase ( pResult - > GetString ( 0 ) , " no " ) = = 0 )
2011-11-08 11:06:09 +00:00
pSelf - > m_VoteEnforce = CGameContext : : VOTE_ENFORCE_NO_ADMIN ;
pSelf - > m_VoteEnforcer = pResult - > m_ClientID ;
2011-01-29 00:59:50 +00:00
char aBuf [ 256 ] ;
2014-09-06 19:19:44 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " moderator forced vote %s " , pResult - > GetString ( 0 ) ) ;
2011-07-10 11:02:13 +00:00
pSelf - > SendChatTarget ( - 1 , aBuf ) ;
2010-08-17 22:06:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " forcing vote %s " , pResult - > GetString ( 0 ) ) ;
2011-08-13 00:11:06 +00:00
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 )
{
2011-08-13 00:11:06 +00:00
pfnCallback ( pResult , pCallbackUserData ) ;
2010-05-29 07:25:38 +00:00
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 > ( ) ;
2017-10-13 00:25:50 +00:00
m_pStorage = Kernel ( ) - > RequestInterface < IStorage > ( ) ;
2010-09-16 22:40:44 +00:00
2011-10-31 18:08:21 +00:00
m_ChatPrintCBIndex = Console ( ) - > RegisterPrintCallback ( 0 , SendChatResponse , this ) ;
2011-08-31 13:41:32 +00:00
2015-12-28 15:14:52 +00:00
Console ( ) - > Register ( " tune " , " s[tuning] i[value] " , CFGFLAG_SERVER | CFGFLAG_GAME , ConTuneParam , this , " Tune variable to value " ) ;
2015-08-27 11:00:43 +00:00
Console ( ) - > Register ( " tune_reset " , " " , CFGFLAG_SERVER , ConTuneReset , this , " Reset tuning " ) ;
Console ( ) - > Register ( " tune_dump " , " " , CFGFLAG_SERVER , ConTuneDump , this , " Dump tuning " ) ;
2015-12-28 15:14:52 +00:00
Console ( ) - > Register ( " tune_zone " , " i[zone] s[tuning] i[value] " , CFGFLAG_SERVER | CFGFLAG_GAME , ConTuneZone , this , " Tune in zone a variable to value " ) ;
Console ( ) - > Register ( " tune_zone_dump " , " i[zone] " , CFGFLAG_SERVER , ConTuneDumpZone , this , " Dump zone tuning in zone x " ) ;
Console ( ) - > Register ( " tune_zone_reset " , " ?i[zone] " , CFGFLAG_SERVER , ConTuneResetZone , this , " reset zone tuning in zone x or in all zones " ) ;
Console ( ) - > Register ( " tune_zone_enter " , " i[zone] s[message] " , CFGFLAG_SERVER | CFGFLAG_GAME , ConTuneSetZoneMsgEnter , this , " which message to display on zone enter; use 0 for normal area " ) ;
Console ( ) - > Register ( " tune_zone_leave " , " i[zone] s[message] " , CFGFLAG_SERVER | CFGFLAG_GAME , ConTuneSetZoneMsgLeave , this , " which message to display on zone leave; use 0 for normal area " ) ;
Console ( ) - > Register ( " switch_open " , " i['0'|'1'] " , CFGFLAG_SERVER | CFGFLAG_GAME , ConSwitchOpen , this , " Whether a switch is open by default (otherwise closed) " ) ;
2012-04-12 00:09:31 +00:00
Console ( ) - > Register ( " pause_game " , " " , CFGFLAG_SERVER , ConPause , this , " Pause/unpause game " ) ;
2015-12-28 15:14:52 +00:00
Console ( ) - > Register ( " change_map " , " ?r[map] " , CFGFLAG_SERVER | CFGFLAG_STORE , ConChangeMap , this , " Change map " ) ;
Console ( ) - > Register ( " random_map " , " ?i[stars] " , CFGFLAG_SERVER , ConRandomMap , this , " Random map " ) ;
Console ( ) - > Register ( " random_unfinished_map " , " ?i[stars] " , CFGFLAG_SERVER , ConRandomUnfinishedMap , this , " Random unfinished map " ) ;
Console ( ) - > Register ( " restart " , " ?i[seconds] " , CFGFLAG_SERVER | CFGFLAG_STORE , ConRestart , this , " Restart in x seconds (0 = abort) " ) ;
Console ( ) - > Register ( " broadcast " , " r[message] " , CFGFLAG_SERVER , ConBroadcast , this , " Broadcast message " ) ;
Console ( ) - > Register ( " say " , " r[message] " , CFGFLAG_SERVER , ConSay , this , " Say in chat " ) ;
Console ( ) - > Register ( " set_team " , " i[id] i[team-id] ?i[delay in minutes] " , CFGFLAG_SERVER , ConSetTeam , this , " Set team of player to team " ) ;
Console ( ) - > Register ( " set_team_all " , " i[team-id] " , CFGFLAG_SERVER , ConSetTeamAll , this , " Set team of all players to team " ) ;
2011-07-14 20:07:21 +00:00
2015-12-28 15:14:52 +00:00
Console ( ) - > Register ( " add_vote " , " s[name] r[command] " , CFGFLAG_SERVER , ConAddVote , this , " Add a voting option " ) ;
Console ( ) - > Register ( " remove_vote " , " s[name] " , CFGFLAG_SERVER , ConRemoveVote , this , " remove a voting option " ) ;
Console ( ) - > Register ( " force_vote " , " s[name] s[command] ?r[reason] " , CFGFLAG_SERVER , ConForceVote , this , " Force a voting option " ) ;
2011-07-14 20:07:21 +00:00
Console ( ) - > Register ( " clear_votes " , " " , CFGFLAG_SERVER , ConClearVotes , this , " Clears the voting options " ) ;
2015-12-28 15:14:52 +00:00
Console ( ) - > Register ( " vote " , " r['yes'|'no'] " , CFGFLAG_SERVER , ConVote , this , " Force a vote to yes/no " ) ;
2010-05-29 07:25:38 +00:00
Console ( ) - > Chain ( " sv_motd " , ConchainSpecialMotdupdate , this ) ;
2010-10-10 22:40:07 +00:00
2017-09-13 20:35:09 +00:00
# define CONSOLE_COMMAND(name, params, flags, callback, userdata, help) m_pConsole->Register(name, params, flags, callback, userdata, help);
# include <game/ddracecommands.h>
# define CHAT_COMMAND(name, params, flags, callback, userdata, help) m_pConsole->Register(name, params, flags, callback, userdata, help);
# include "ddracechat.h"
2010-05-29 07:25:38 +00:00
}
void CGameContext : : OnInit ( /*class IKernel *pKernel*/ )
{
m_pServer = Kernel ( ) - > RequestInterface < IServer > ( ) ;
m_pConsole = Kernel ( ) - > RequestInterface < IConsole > ( ) ;
2017-10-13 00:25:50 +00:00
m_pStorage = Kernel ( ) - > RequestInterface < IStorage > ( ) ;
2010-05-29 07:25:38 +00:00
m_World . SetGameServer ( this ) ;
m_Events . SetGameServer ( this ) ;
2011-04-13 18:37:12 +00:00
2017-09-12 12:58:44 +00:00
m_GameUuid = RandomUuid ( ) ;
2017-09-13 20:35:09 +00:00
Console ( ) - > SetTeeHistorianCommandCallback ( CommandCallback , this ) ;
2017-09-12 12:58:44 +00:00
2015-07-14 20:08:29 +00:00
DeleteTempfile ( ) ;
2010-05-29 07:25:38 +00:00
//if(!data) // only load once
//data = load_data_from_memory(internal_data);
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
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];
2014-03-12 23:31:50 +00:00
// Reset Tunezones
CTuningParams TuningParams ;
2017-07-26 01:58:00 +00:00
for ( int i = 0 ; i < NUM_TUNEZONES ; i + + )
2014-03-12 23:31:50 +00:00
{
2014-03-23 18:31:28 +00:00
TuningList ( ) [ i ] = TuningParams ;
TuningList ( ) [ i ] . Set ( " gun_curvature " , 0 ) ;
TuningList ( ) [ i ] . Set ( " gun_speed " , 1400 ) ;
TuningList ( ) [ i ] . Set ( " shotgun_curvature " , 0 ) ;
TuningList ( ) [ i ] . Set ( " shotgun_speed " , 500 ) ;
TuningList ( ) [ i ] . Set ( " shotgun_speeddiff " , 0 ) ;
2014-03-12 23:31:50 +00:00
}
2014-03-23 18:31:28 +00:00
2017-07-26 01:58:00 +00:00
for ( int i = 0 ; i < NUM_TUNEZONES ; i + + )
2014-03-12 23:31:50 +00:00
{
2017-07-26 01:58:00 +00:00
// Send no text by default when changing tune zones.
m_aaZoneEnterMsg [ i ] [ 0 ] = 0 ;
m_aaZoneLeaveMsg [ i ] [ 0 ] = 0 ;
2014-03-12 23:31:50 +00:00
}
2011-05-30 20:05:28 +00:00
// Reset Tuning
2011-09-02 18:37:03 +00:00
if ( g_Config . m_SvTuneReset )
{
ResetTuning ( ) ;
}
2011-09-05 11:55:47 +00:00
else
{
Tuning ( ) - > Set ( " gun_speed " , 1400 ) ;
Tuning ( ) - > Set ( " gun_curvature " , 0 ) ;
Tuning ( ) - > Set ( " shotgun_speed " , 500 ) ;
Tuning ( ) - > Set ( " shotgun_speeddiff " , 0 ) ;
Tuning ( ) - > Set ( " shotgun_curvature " , 0 ) ;
}
2011-09-02 18:37:03 +00:00
if ( g_Config . m_SvDDRaceTuneReset )
{
g_Config . m_SvHit = 1 ;
g_Config . m_SvEndlessDrag = 0 ;
g_Config . m_SvOldLaser = 0 ;
2013-11-24 18:23:58 +00:00
g_Config . m_SvOldTeleportHook = 0 ;
g_Config . m_SvOldTeleportWeapons = 0 ;
2014-04-04 22:35:18 +00:00
g_Config . m_SvTeleportHoldHook = 0 ;
2014-11-25 21:42:05 +00:00
g_Config . m_SvTeam = 1 ;
g_Config . m_SvShowOthersDefault = 0 ;
2015-07-22 21:31:50 +00:00
if ( Collision ( ) - > m_NumSwitchers > 0 )
for ( int i = 0 ; i < Collision ( ) - > m_NumSwitchers + 1 ; + + i )
Collision ( ) - > m_pSwitchers [ i ] . m_Initial = true ;
2011-09-02 18:37:03 +00:00
}
2011-05-30 20:05:28 +00:00
2016-05-02 19:35:32 +00:00
Console ( ) - > ExecuteFile ( g_Config . m_SvResetFile , - 1 ) ;
2013-07-21 21:42:08 +00:00
2015-07-15 12:02:21 +00:00
LoadMapSettings ( ) ;
2017-10-10 00:39:29 +00:00
m_pController = new CGameControllerDDRace ( this ) ;
( ( CGameControllerDDRace * ) m_pController ) - > m_Teams . Reset ( ) ;
2017-09-12 12:58:44 +00:00
m_TeeHistorianActive = g_Config . m_SvTeeHistorian ;
if ( m_TeeHistorianActive )
{
char aGameUuid [ UUID_MAXSTRSIZE ] ;
FormatUuid ( m_GameUuid , aGameUuid , sizeof ( aGameUuid ) ) ;
char aFilename [ 64 ] ;
str_format ( aFilename , sizeof ( aFilename ) , " teehistorian/%s.teehistorian " , aGameUuid ) ;
2017-10-13 00:25:50 +00:00
IOHANDLE File = Storage ( ) - > OpenFile ( aFilename , IOFLAG_WRITE , IStorage : : TYPE_SAVE ) ;
2017-10-10 02:07:38 +00:00
if ( ! File )
2017-09-12 12:58:44 +00:00
{
dbg_msg ( " teehistorian " , " failed to open '%s' " , aFilename ) ;
2017-10-13 00:25:50 +00:00
Server ( ) - > SetErrorShutdown ( " teehistorian open error " ) ;
return ;
2017-09-12 12:58:44 +00:00
}
else
{
dbg_msg ( " teehistorian " , " recording to '%s' " , aFilename ) ;
}
2017-10-13 00:48:42 +00:00
m_pTeeHistorianFile = aio_new ( File ) ;
2017-09-12 12:58:44 +00:00
char aVersion [ 128 ] ;
# ifdef GIT_SHORTREV_HASH
str_format ( aVersion , sizeof ( aVersion ) , " %s (%s) " , GAME_VERSION , GIT_SHORTREV_HASH ) ;
# else
str_format ( aVersion , sizeof ( aVersion ) , " %s " , GAME_VERSION ) ;
# endif
CTeeHistorian : : CGameInfo GameInfo ;
GameInfo . m_GameUuid = m_GameUuid ;
GameInfo . m_pServerVersion = aVersion ;
GameInfo . m_StartTime = time ( 0 ) ;
GameInfo . m_pServerName = g_Config . m_SvName ;
GameInfo . m_ServerPort = g_Config . m_SvPort ;
2017-09-27 17:38:54 +00:00
GameInfo . m_pGameType = m_pController - > m_pGameType ;
2017-09-12 12:58:44 +00:00
2017-09-13 20:35:09 +00:00
GameInfo . m_pConfig = & g_Config ;
GameInfo . m_pTuning = Tuning ( ) ;
2017-09-12 12:58:44 +00:00
char aMapName [ 128 ] ;
Server ( ) - > GetMapInfo ( aMapName , sizeof ( aMapName ) , & GameInfo . m_MapSize , & GameInfo . m_MapCrc ) ;
GameInfo . m_pMapName = aMapName ;
m_TeeHistorian . Reset ( & GameInfo , TeeHistorianWrite , this ) ;
}
2014-11-25 21:42:05 +00:00
if ( g_Config . m_SvSoloServer )
{
g_Config . m_SvTeam = 3 ;
g_Config . m_SvShowOthersDefault = 1 ;
Tuning ( ) - > Set ( " player_collision " , 0 ) ;
Tuning ( ) - > Set ( " player_hooking " , 0 ) ;
2017-07-26 01:58:00 +00:00
for ( int i = 0 ; i < NUM_TUNEZONES ; i + + )
2014-11-25 21:42:05 +00:00
{
TuningList ( ) [ i ] . Set ( " player_collision " , 0 ) ;
TuningList ( ) [ i ] . Set ( " player_hooking " , 0 ) ;
}
}
2010-08-23 19:37:27 +00:00
// delete old score object
if ( m_pScore )
delete m_pScore ;
2011-04-09 06:41:31 +00:00
2010-08-23 19:37:27 +00:00
// create score object (add sql later)
2010-11-16 13:44:16 +00:00
# if defined(CONF_SQL)
2010-08-26 13:27:36 +00:00
if ( g_Config . m_SvUseSQL )
m_pScore = new CSqlScore ( this ) ;
else
2010-11-16 13:44:16 +00:00
# endif
2010-08-23 19:37:27 +00:00
m_pScore = new CFileScore ( this ) ;
2010-05-29 07:25:38 +00:00
// setup core world
//for(int i = 0; i < MAX_CLIENTS; i++)
// game.players[i].core.world = &game.world.core;
2011-01-29 00:59:50 +00:00
2010-05-29 07:25:38 +00:00
// create all entities from the game layer
CMapItemLayerTilemap * pTileMap = m_Layers . GameLayer ( ) ;
CTile * pTiles = ( CTile * ) Kernel ( ) - > RequestInterface < IMap > ( ) - > GetData ( pTileMap - > m_Data ) ;
2011-04-13 18:37:12 +00:00
2011-01-29 00:59:50 +00:00
/*
num_spawn_points [ 0 ] = 0 ;
num_spawn_points [ 1 ] = 0 ;
2011-08-13 00:11:06 +00:00
num_spawn_points [ 2 ] = 0 ;
2011-01-29 00:59:50 +00:00
*/
2011-04-13 18:37:12 +00:00
2010-11-13 13:22:19 +00:00
CTile * pFront = 0 ;
CSwitchTile * pSwitch = 0 ;
2010-10-10 22:40:07 +00:00
if ( m_Layers . FrontLayer ( ) )
2011-08-26 11:46:22 +00:00
pFront = ( CTile * ) Kernel ( ) - > RequestInterface < IMap > ( ) - > GetData ( m_Layers . FrontLayer ( ) - > m_Front ) ;
2010-11-13 13:22:19 +00:00
if ( m_Layers . SwitchLayer ( ) )
2011-08-26 11:46:22 +00:00
pSwitch = ( CSwitchTile * ) Kernel ( ) - > RequestInterface < IMap > ( ) - > GetData ( m_Layers . SwitchLayer ( ) - > m_Switch ) ;
2010-08-20 20:40:12 +00:00
2010-05-29 07:25:38 +00:00
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 ;
2011-04-13 18:37:12 +00:00
2010-12-01 22:45:04 +00:00
if ( Index = = TILE_OLDLASER )
2010-12-01 23:33:02 +00:00
{
2010-12-01 22:45:04 +00:00
g_Config . m_SvOldLaser = 1 ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " game layer " , " found old laser tile " ) ;
2010-12-01 23:33:02 +00:00
}
2010-12-01 22:45:04 +00:00
else if ( Index = = TILE_NPC )
2010-12-01 23:33:02 +00:00
{
2011-01-29 00:59:50 +00:00
m_Tuning . Set ( " player_collision " , 0 ) ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " game layer " , " found no collision tile " ) ;
2010-12-01 23:33:02 +00:00
}
2010-10-10 22:40:07 +00:00
else if ( Index = = TILE_EHOOK )
2010-12-01 23:33:02 +00:00
{
2010-08-28 19:34:21 +00:00
g_Config . m_SvEndlessDrag = 1 ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " game layer " , " found no unlimited hook time tile " ) ;
2010-12-01 23:33:02 +00:00
}
2010-10-10 22:40:07 +00:00
else if ( Index = = TILE_NOHIT )
2010-12-01 23:33:02 +00:00
{
2010-08-28 19:34:21 +00:00
g_Config . m_SvHit = 0 ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " game layer " , " found no weapons hitting others tile " ) ;
2010-12-01 23:33:02 +00:00
}
2010-10-10 22:40:07 +00:00
else if ( Index = = TILE_NPH )
2010-12-01 23:33:02 +00:00
{
2011-01-29 00:59:50 +00:00
m_Tuning . Set ( " player_hooking " , 0 ) ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " game layer " , " found no player hooking tile " ) ;
2010-12-01 23:33:02 +00:00
}
2011-04-09 06:41:31 +00:00
2010-05-29 07:25:38 +00:00
if ( Index > = ENTITY_OFFSET )
{
vec2 Pos ( x * 32.0f + 16.0f , y * 32.0f + 16.0f ) ;
2011-04-09 06:41:31 +00:00
//m_pController->OnEntity(Index-ENTITY_OFFSET, Pos);
2011-01-29 00:59:50 +00:00
m_pController - > OnEntity ( Index - ENTITY_OFFSET , Pos , LAYER_GAME , pTiles [ y * pTileMap - > m_Width + x ] . m_Flags ) ;
2010-08-20 20:40:12 +00:00
}
2011-04-09 06:41:31 +00:00
2010-10-10 22:40:07 +00:00
if ( pFront )
2010-08-20 20:40:12 +00:00
{
2011-01-29 00:59:50 +00:00
Index = pFront [ y * pTileMap - > m_Width + x ] . m_Index ;
2010-12-01 22:45:04 +00:00
if ( Index = = TILE_OLDLASER )
2011-01-29 00:59:50 +00:00
{
2010-12-01 22:45:04 +00:00
g_Config . m_SvOldLaser = 1 ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " front layer " , " found old laser tile " ) ;
2011-01-29 00:59:50 +00:00
}
2010-12-01 22:45:04 +00:00
else if ( Index = = TILE_NPC )
2011-01-29 00:59:50 +00:00
{
m_Tuning . Set ( " player_collision " , 0 ) ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " front layer " , " found no collision tile " ) ;
2011-01-29 00:59:50 +00:00
}
2010-10-10 22:40:07 +00:00
else if ( Index = = TILE_EHOOK )
2011-01-29 00:59:50 +00:00
{
2010-08-28 19:34:21 +00:00
g_Config . m_SvEndlessDrag = 1 ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " front layer " , " found no unlimited hook time tile " ) ;
2011-01-29 00:59:50 +00:00
}
2010-10-10 22:40:07 +00:00
else if ( Index = = TILE_NOHIT )
2011-01-29 00:59:50 +00:00
{
2010-08-28 19:34:21 +00:00
g_Config . m_SvHit = 0 ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " front layer " , " found no weapons hitting others tile " ) ;
2011-01-29 00:59:50 +00:00
}
2010-10-10 22:40:07 +00:00
else if ( Index = = TILE_NPH )
2011-01-29 00:59:50 +00:00
{
m_Tuning . Set ( " player_hooking " , 0 ) ;
2016-05-02 19:35:32 +00:00
dbg_msg ( " front layer " , " found no player hooking tile " ) ;
2011-01-29 00:59:50 +00:00
}
2010-08-27 23:30:50 +00:00
if ( Index > = ENTITY_OFFSET )
2010-08-20 20:40:12 +00:00
{
vec2 Pos ( x * 32.0f + 16.0f , y * 32.0f + 16.0f ) ;
2010-11-13 13:22:19 +00:00
m_pController - > OnEntity ( Index - ENTITY_OFFSET , Pos , LAYER_FRONT , pFront [ y * pTileMap - > m_Width + x ] . m_Flags ) ;
}
}
if ( pSwitch )
{
2011-01-29 00:59:50 +00:00
Index = pSwitch [ y * pTileMap - > m_Width + x ] . m_Type ;
2013-08-22 22:45:48 +00:00
// TODO: Add off by default door here
// if (Index == TILE_DOOR_OFF)
2010-11-13 13:22:19 +00:00
if ( Index > = ENTITY_OFFSET )
{
vec2 Pos ( x * 32.0f + 16.0f , y * 32.0f + 16.0f ) ;
2010-11-14 14:00:33 +00:00
m_pController - > OnEntity ( Index - ENTITY_OFFSET , Pos , LAYER_SWITCH , pSwitch [ y * pTileMap - > m_Width + x ] . m_Flags , pSwitch [ y * pTileMap - > m_Width + x ] . m_Number ) ;
2010-08-20 20:40:12 +00:00
}
2010-05-29 07:25:38 +00:00
}
}
}
2011-01-29 00:59:50 +00:00
//game.world.insert_entity(game.Controller);
2010-05-29 07:25:38 +00:00
# ifdef CONF_DEBUG
if ( g_Config . m_DbgDummies )
{
for ( int i = 0 ; i < g_Config . m_DbgDummies ; i + + )
{
OnClientConnected ( MAX_CLIENTS - i - 1 ) ;
}
}
# endif
}
2015-07-14 20:08:29 +00:00
void CGameContext : : DeleteTempfile ( )
{
if ( m_aDeleteTempfile [ 0 ] ! = 0 )
{
2017-10-13 00:25:50 +00:00
Storage ( ) - > RemoveFile ( m_aDeleteTempfile , IStorage : : TYPE_SAVE ) ;
2015-07-14 20:08:29 +00:00
m_aDeleteTempfile [ 0 ] = 0 ;
}
}
void CGameContext : : OnMapChange ( char * pNewMapName , int MapNameSize )
{
char aConfig [ 128 ] ;
char aTemp [ 128 ] ;
str_format ( aConfig , sizeof ( aConfig ) , " maps/%s.cfg " , g_Config . m_SvMap ) ;
2015-08-21 21:02:50 +00:00
str_format ( aTemp , sizeof ( aTemp ) , " %s.temp.%d " , pNewMapName , pid ( ) ) ;
2015-07-14 20:08:29 +00:00
2017-10-13 00:25:50 +00:00
IOHANDLE File = Storage ( ) - > OpenFile ( aConfig , IOFLAG_READ , IStorage : : TYPE_ALL ) ;
2015-07-14 20:08:29 +00:00
if ( ! File )
{
// No map-specific config, just return.
return ;
}
CLineReader LineReader ;
LineReader . Init ( File ) ;
array < char * > aLines ;
char * pLine ;
int TotalLength = 0 ;
while ( ( pLine = LineReader . Get ( ) ) )
{
int Length = str_length ( pLine ) + 1 ;
char * pCopy = ( char * ) mem_alloc ( Length , 1 ) ;
mem_copy ( pCopy , pLine , Length ) ;
aLines . add ( pCopy ) ;
TotalLength + = Length ;
}
2017-07-08 11:38:27 +00:00
io_close ( File ) ;
2015-07-14 20:08:29 +00:00
char * pSettings = ( char * ) mem_alloc ( TotalLength , 1 ) ;
int Offset = 0 ;
for ( int i = 0 ; i < aLines . size ( ) ; i + + )
{
int Length = str_length ( aLines [ i ] ) + 1 ;
mem_copy ( pSettings + Offset , aLines [ i ] , Length ) ;
2015-07-15 09:38:42 +00:00
Offset + = Length ;
2015-07-14 20:08:29 +00:00
mem_free ( aLines [ i ] ) ;
}
CDataFileReader Reader ;
2017-10-13 00:25:50 +00:00
Reader . Open ( Storage ( ) , pNewMapName , IStorage : : TYPE_ALL ) ;
2015-07-14 20:08:29 +00:00
CDataFileWriter Writer ;
2015-08-27 11:37:34 +00:00
Writer . Init ( ) ;
2015-07-14 20:08:29 +00:00
int SettingsIndex = Reader . NumData ( ) ;
2015-08-27 13:46:51 +00:00
bool FoundInfo = false ;
2015-07-14 20:08:29 +00:00
for ( int i = 0 ; i < Reader . NumItems ( ) ; i + + )
{
int TypeID ;
int ItemID ;
int * pData = ( int * ) Reader . GetItem ( i , & TypeID , & ItemID ) ;
2017-08-28 16:06:19 +00:00
int Size = Reader . GetItemSize ( i ) ;
2015-07-14 20:08:29 +00:00
CMapItemInfoSettings MapInfo ;
if ( TypeID = = MAPITEMTYPE_INFO & & ItemID = = 0 )
{
2015-08-27 13:46:51 +00:00
FoundInfo = true ;
2015-07-14 20:08:29 +00:00
CMapItemInfoSettings * pInfo = ( CMapItemInfoSettings * ) pData ;
if ( Size > = ( int ) sizeof ( CMapItemInfoSettings ) )
{
2015-08-21 21:02:50 +00:00
if ( pInfo - > m_Settings > - 1 )
2015-07-14 20:08:29 +00:00
{
2015-08-21 21:02:50 +00:00
SettingsIndex = pInfo - > m_Settings ;
char * pMapSettings = ( char * ) Reader . GetData ( SettingsIndex ) ;
2017-08-30 06:36:17 +00:00
int DataSize = Reader . GetDataSize ( SettingsIndex ) ;
2015-08-27 14:20:56 +00:00
if ( DataSize = = TotalLength & & mem_comp ( pSettings , pMapSettings , DataSize ) = = 0 )
2015-08-21 21:02:50 +00:00
{
// Configs coincide, no need to update map.
return ;
}
Reader . UnloadData ( pInfo - > m_Settings ) ;
}
else
{
MapInfo = * pInfo ;
MapInfo . m_Settings = SettingsIndex ;
pData = ( int * ) & MapInfo ;
Size = sizeof ( MapInfo ) ;
2015-07-14 20:08:29 +00:00
}
}
else
{
* ( CMapItemInfo * ) & MapInfo = * ( CMapItemInfo * ) pInfo ;
MapInfo . m_Settings = SettingsIndex ;
pData = ( int * ) & MapInfo ;
Size = sizeof ( MapInfo ) ;
}
}
Writer . AddItem ( TypeID , ItemID , Size , pData ) ;
}
2015-08-27 13:46:51 +00:00
if ( ! FoundInfo )
{
CMapItemInfoSettings Info ;
Info . m_Version = 1 ;
Info . m_Author = - 1 ;
Info . m_MapVersion = - 1 ;
Info . m_Credits = - 1 ;
Info . m_License = - 1 ;
Info . m_Settings = SettingsIndex ;
Writer . AddItem ( MAPITEMTYPE_INFO , 0 , sizeof ( Info ) , & Info ) ;
}
2015-07-14 20:08:29 +00:00
for ( int i = 0 ; i < Reader . NumData ( ) | | i = = SettingsIndex ; i + + )
{
if ( i = = SettingsIndex )
{
Writer . AddData ( TotalLength , pSettings ) ;
continue ;
}
unsigned char * pData = ( unsigned char * ) Reader . GetData ( i ) ;
2017-08-30 06:36:17 +00:00
int Size = Reader . GetDataSize ( i ) ;
2015-07-14 20:08:29 +00:00
Writer . AddData ( Size , pData ) ;
Reader . UnloadData ( i ) ;
}
dbg_msg ( " mapchange " , " imported settings " ) ;
Reader . Close ( ) ;
2017-10-13 00:25:50 +00:00
Writer . OpenFile ( Storage ( ) , aTemp ) ;
2015-07-14 20:08:29 +00:00
Writer . Finish ( ) ;
str_copy ( pNewMapName , aTemp , MapNameSize ) ;
str_copy ( m_aDeleteTempfile , aTemp , sizeof ( m_aDeleteTempfile ) ) ;
}
2016-05-04 13:32:24 +00:00
void CGameContext : : OnShutdown ( bool FullShutdown )
2010-05-29 07:25:38 +00:00
{
2016-05-04 13:32:24 +00:00
if ( FullShutdown )
Score ( ) - > OnShutdown ( ) ;
2017-09-12 12:58:44 +00:00
if ( m_TeeHistorianActive )
{
m_TeeHistorian . Finish ( ) ;
2017-10-13 00:48:42 +00:00
aio_close ( m_pTeeHistorianFile ) ;
aio_wait ( m_pTeeHistorianFile ) ;
int Error = aio_error ( m_pTeeHistorianFile ) ;
2017-10-10 02:07:38 +00:00
if ( Error )
{
dbg_msg ( " teehistorian " , " error closing file, err=%d " , Error ) ;
2017-10-13 00:25:50 +00:00
Server ( ) - > SetErrorShutdown ( " teehistorian close error " ) ;
2017-10-10 02:07:38 +00:00
}
2017-10-13 00:48:42 +00:00
aio_free ( m_pTeeHistorianFile ) ;
2017-09-12 12:58:44 +00:00
}
2015-07-14 20:08:29 +00:00
DeleteTempfile ( ) ;
2015-07-15 12:02:21 +00:00
Console ( ) - > ResetServerGameSettings ( ) ;
2010-10-27 10:14:26 +00:00
Collision ( ) - > Dest ( ) ;
2010-05-29 07:25:38 +00:00
delete m_pController ;
m_pController = 0 ;
Clear ( ) ;
2008-08-14 18:42:47 +00:00
}
2011-07-13 20:38:32 +00:00
void CGameContext : : LoadMapSettings ( )
{
IMap * pMap = Kernel ( ) - > RequestInterface < IMap > ( ) ;
int Start , Num ;
pMap - > GetType ( MAPITEMTYPE_INFO , & Start , & Num ) ;
for ( int i = Start ; i < Start + Num ; i + + )
{
int ItemID ;
CMapItemInfoSettings * pItem = ( CMapItemInfoSettings * ) pMap - > GetItem ( i , 0 , & ItemID ) ;
2017-08-28 16:06:19 +00:00
int ItemSize = pMap - > GetItemSize ( i ) ;
2011-07-13 20:38:32 +00:00
if ( ! pItem | | ItemID ! = 0 )
continue ;
if ( ItemSize < ( int ) sizeof ( CMapItemInfoSettings ) )
break ;
if ( ! ( pItem - > m_Settings > - 1 ) )
break ;
2017-08-30 06:36:17 +00:00
int Size = pMap - > GetDataSize ( pItem - > m_Settings ) ;
2011-07-13 20:38:32 +00:00
char * pSettings = ( char * ) pMap - > GetData ( pItem - > m_Settings ) ;
char * pNext = pSettings ;
while ( pNext < pSettings + Size )
{
int StrSize = str_length ( pNext ) + 1 ;
2015-07-15 12:02:21 +00:00
Console ( ) - > ExecuteLine ( pNext , IConsole : : CLIENT_ID_GAME ) ;
2011-07-13 20:38:32 +00:00
pNext + = StrSize ;
}
pMap - > UnloadData ( pItem - > m_Settings ) ;
2015-08-21 21:02:50 +00:00
break ;
2011-07-13 20:38:32 +00:00
}
2015-07-15 12:02:21 +00:00
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " maps/%s.map.cfg " , g_Config . m_SvMap ) ;
Console ( ) - > ExecuteFile ( aBuf , IConsole : : CLIENT_ID_NO_GAME ) ;
2011-07-13 20:38:32 +00:00
}
2011-02-12 10:40:36 +00:00
void CGameContext : : OnSnap ( int ClientID )
2008-08-14 18:42:47 +00:00
{
2012-01-08 23:49:20 +00:00
// add tuning to demo
CTuningParams StandardTuning ;
if ( ClientID = = - 1 & & Server ( ) - > DemoRecorder_IsRecording ( ) & & mem_comp ( & StandardTuning , & m_Tuning , sizeof ( CTuningParams ) ) ! = 0 )
{
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 ] ) ;
Server ( ) - > SendMsg ( & Msg , MSGFLAG_RECORD | MSGFLAG_NOSEND , ClientID ) ;
}
2011-02-12 10:40:36 +00:00
m_World . Snap ( ClientID ) ;
m_pController - > Snap ( ClientID ) ;
m_Events . Snap ( ClientID ) ;
2011-04-13 18:37:12 +00:00
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
}
2014-09-26 01:20:47 +00:00
if ( ClientID > - 1 )
2016-09-20 19:40:40 +00:00
m_apPlayers [ ClientID ] - > FakeSnap ( ) ;
2013-12-31 05:13:57 +00:00
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 ; }
IGameServer * CreateGameServer ( ) { return new CGameContext ; }
2010-09-17 09:34:13 +00:00
2011-01-29 00:59:50 +00:00
void CGameContext : : SendChatResponseAll ( const char * pLine , void * pUser )
{
CGameContext * pSelf = ( CGameContext * ) pUser ;
static volatile int ReentryGuard = 0 ;
2014-12-02 11:35:52 +00:00
const char * pLineOrig = pLine ;
2011-01-29 00:59:50 +00:00
if ( ReentryGuard )
return ;
ReentryGuard + + ;
if ( * pLine = = ' [ ' )
do
pLine + + ;
2014-12-02 11:35:52 +00:00
while ( ( pLine - 2 < pLineOrig | | * ( pLine - 2 ) ! = ' : ' ) & & * pLine ! = 0 ) ; //remove the category (e.g. [Console]: No Such Command)
2011-01-29 00:59:50 +00:00
pSelf - > SendChat ( - 1 , CHAT_ALL , pLine ) ;
ReentryGuard - - ;
}
2014-12-20 15:35:47 +00:00
void CGameContext : : SendChatResponse ( const char * pLine , void * pUser , bool Highlighted )
2011-01-29 00:59:50 +00:00
{
2011-08-31 13:41:32 +00:00
CGameContext * pSelf = ( CGameContext * ) pUser ;
int ClientID = pSelf - > m_ChatResponseTargetID ;
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS )
return ;
2011-01-29 00:59:50 +00:00
2014-12-02 11:35:52 +00:00
const char * pLineOrig = pLine ;
2011-01-29 00:59:50 +00:00
static volatile int ReentryGuard = 0 ;
if ( ReentryGuard )
return ;
ReentryGuard + + ;
2017-08-21 18:48:11 +00:00
if ( pLine [ 0 ] = = ' [ ' )
{
// Remove time and category: [20:39:00][Console]
pLine = str_find ( pLine , " ]: " ) ;
if ( pLine )
pLine + = 3 ;
else
pLine = pLineOrig ;
}
2011-01-29 00:59:50 +00:00
2011-08-31 13:41:32 +00:00
pSelf - > SendChatTarget ( ClientID , pLine ) ;
2011-01-29 00:59:50 +00:00
ReentryGuard - - ;
}
bool CGameContext : : PlayerCollision ( )
{
float Temp ;
m_Tuning . Get ( " player_collision " , & Temp ) ;
return Temp ! = 0.0 ;
}
bool CGameContext : : PlayerHooking ( )
{
float Temp ;
m_Tuning . Get ( " player_hooking " , & Temp ) ;
return Temp ! = 0.0 ;
}
2013-11-13 12:25:26 +00:00
float CGameContext : : PlayerJetpack ( )
{
float Temp ;
m_Tuning . Get ( " player_jetpack " , & Temp ) ;
return Temp ;
}
2011-02-13 05:35:13 +00:00
void CGameContext : : OnSetAuthed ( int ClientID , int Level )
2011-01-29 00:59:50 +00:00
{
2011-02-13 05:35:13 +00:00
if ( m_apPlayers [ ClientID ] )
2011-01-29 00:59:50 +00:00
{
2011-02-13 05:35:13 +00:00
m_apPlayers [ ClientID ] - > m_Authed = Level ;
2011-08-13 00:11:06 +00:00
char aBuf [ 512 ] , aIP [ NETADDR_MAXSTRSIZE ] ;
2017-06-06 03:51:12 +00:00
Server ( ) - > GetClientAddr ( ClientID , aIP , sizeof ( aIP ) ) ;
2011-07-20 00:41:11 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " ban %s %d Banned by vote " , aIP , g_Config . m_SvVoteKickBantime ) ;
2011-04-14 02:26:13 +00:00
if ( ! str_comp_nocase ( m_aVoteCommand , aBuf ) & & Level > 0 )
2011-01-29 00:59:50 +00:00
{
2011-12-26 09:15:43 +00:00
m_VoteEnforce = CGameContext : : VOTE_ENFORCE_NO_ADMIN ;
2011-02-23 13:55:27 +00:00
Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_STANDARD , " CGameContext " , " Aborted vote by admin login. " ) ;
2011-01-29 00:59:50 +00:00
}
}
}
2011-02-27 08:07:57 +00:00
void CGameContext : : SendRecord ( int ClientID )
{
2011-01-29 00:59:50 +00:00
CNetMsg_Sv_Record RecordsMsg ;
2011-04-14 02:38:03 +00:00
RecordsMsg . m_PlayerTimeBest = Score ( ) - > PlayerData ( ClientID ) - > m_BestTime * 100.0f ;
RecordsMsg . m_ServerTimeBest = m_pController - > m_CurrentRecord * 100.0f ; //TODO: finish this
2011-02-13 05:35:13 +00:00
Server ( ) - > SendPackMsg ( & RecordsMsg , MSGFLAG_VITAL , ClientID ) ;
2011-02-23 07:43:05 +00:00
}
2011-02-27 08:07:57 +00:00
int CGameContext : : ProcessSpamProtection ( int ClientID )
{
2011-09-07 23:02:09 +00:00
if ( ! m_apPlayers [ ClientID ] )
return 0 ;
2011-04-09 06:41:31 +00:00
if ( g_Config . m_SvSpamprotection & & m_apPlayers [ ClientID ] - > m_LastChat
& & m_apPlayers [ ClientID ] - > m_LastChat + Server ( ) - > TickSpeed ( ) * g_Config . m_SvChatDelay > Server ( ) - > Tick ( ) )
2011-02-27 08:07:57 +00:00
return 1 ;
else
2011-04-09 06:41:31 +00:00
m_apPlayers [ ClientID ] - > m_LastChat = Server ( ) - > Tick ( ) ;
2011-02-27 08:07:57 +00:00
NETADDR Addr ;
Server ( ) - > GetClientAddr ( ClientID , & Addr ) ;
int Muted = 0 ;
for ( int i = 0 ; i < m_NumMutes & & ! Muted ; i + + )
{
if ( ! net_addr_comp ( & Addr , & m_aMutes [ i ] . m_Addr ) )
Muted = ( m_aMutes [ i ] . m_Expire - Server ( ) - > Tick ( ) ) / Server ( ) - > TickSpeed ( ) ;
}
if ( Muted > 0 )
{
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof aBuf , " You are not permitted to talk for the next %d seconds. " , Muted ) ;
SendChatTarget ( ClientID , aBuf ) ;
return 1 ;
}
if ( ( m_apPlayers [ ClientID ] - > m_ChatScore + = g_Config . m_SvChatPenalty ) > g_Config . m_SvChatThreshold )
{
2011-04-12 20:18:15 +00:00
Mute ( 0 , & Addr , g_Config . m_SvSpamMuteDuration , Server ( ) - > ClientName ( ClientID ) ) ;
2011-02-27 08:07:57 +00:00
m_apPlayers [ ClientID ] - > m_ChatScore = 0 ;
return 1 ;
}
return 0 ;
}
2011-04-19 19:44:02 +00:00
int CGameContext : : GetDDRaceTeam ( int ClientID )
{
2017-03-21 10:24:44 +00:00
CGameControllerDDRace * pController = ( CGameControllerDDRace * ) m_pController ;
2011-04-19 19:44:02 +00:00
return pController - > m_Teams . m_Core . Team ( ClientID ) ;
}
2011-05-30 20:05:28 +00:00
void CGameContext : : ResetTuning ( )
{
CTuningParams TuningParams ;
m_Tuning = TuningParams ;
Tuning ( ) - > Set ( " gun_speed " , 1400 ) ;
Tuning ( ) - > Set ( " gun_curvature " , 0 ) ;
Tuning ( ) - > Set ( " shotgun_speed " , 500 ) ;
Tuning ( ) - > Set ( " shotgun_speeddiff " , 0 ) ;
Tuning ( ) - > Set ( " shotgun_curvature " , 0 ) ;
SendTuningParams ( - 1 ) ;
}
2013-08-09 13:04:20 +00:00
bool CheckClientID2 ( int ClientID )
{
if ( ClientID < 0 | | ClientID > = MAX_CLIENTS )
return false ;
return true ;
}
void CGameContext : : Whisper ( int ClientID , char * pStr )
{
char * pName ;
char * pMessage ;
int Error = 0 ;
2013-08-10 01:40:59 +00:00
if ( ProcessSpamProtection ( ClientID ) )
return ;
2013-08-09 13:04:20 +00:00
pStr = str_skip_whitespaces ( pStr ) ;
2013-08-12 21:02:39 +00:00
int Victim ;
2013-08-09 13:04:20 +00:00
// add token
if ( * pStr = = ' " ' )
{
pStr + + ;
pName = pStr ; // we might have to process escape data
while ( 1 )
{
if ( pStr [ 0 ] = = ' " ' )
break ;
else if ( pStr [ 0 ] = = ' \\ ' )
{
if ( pStr [ 1 ] = = ' \\ ' )
pStr + + ; // skip due to escape
else if ( pStr [ 1 ] = = ' " ' )
pStr + + ; // skip due to escape
}
else if ( pStr [ 0 ] = = 0 )
Error = 1 ;
pStr + + ;
}
// write null termination
* pStr = 0 ;
pStr + + ;
2013-08-12 21:02:39 +00:00
for ( Victim = 0 ; Victim < MAX_CLIENTS ; Victim + + )
if ( str_comp ( pName , Server ( ) - > ClientName ( Victim ) ) = = 0 )
break ;
2013-08-09 13:04:20 +00:00
}
else
{
pName = pStr ;
while ( 1 )
{
2013-08-10 02:30:59 +00:00
if ( pStr [ 0 ] = = 0 )
{
Error = 1 ;
break ;
}
2013-08-09 13:04:20 +00:00
if ( pStr [ 0 ] = = ' ' )
{
2013-08-12 21:02:39 +00:00
pStr [ 0 ] = 0 ;
for ( Victim = 0 ; Victim < MAX_CLIENTS ; Victim + + )
if ( str_comp ( pName , Server ( ) - > ClientName ( Victim ) ) = = 0 )
break ;
pStr [ 0 ] = ' ' ;
if ( Victim < MAX_CLIENTS )
break ;
2013-08-09 13:04:20 +00:00
}
pStr + + ;
}
}
if ( pStr [ 0 ] ! = ' ' )
{
Error = 1 ;
}
* pStr = 0 ;
pStr + + ;
pMessage = pStr ;
char aBuf [ 256 ] ;
if ( Error )
{
str_format ( aBuf , sizeof ( aBuf ) , " Invalid whisper " ) ;
SendChatTarget ( ClientID , aBuf ) ;
return ;
}
if ( Victim > = MAX_CLIENTS | | ! CheckClientID2 ( Victim ) )
{
str_format ( aBuf , sizeof ( aBuf ) , " No player with name \" %s \" found " , pName ) ;
SendChatTarget ( ClientID , aBuf ) ;
return ;
}
2013-10-18 09:42:35 +00:00
WhisperID ( ClientID , Victim , pMessage ) ;
}
void CGameContext : : WhisperID ( int ClientID , int VictimID , char * pMessage )
{
if ( ! CheckClientID2 ( ClientID ) )
return ;
if ( ! CheckClientID2 ( VictimID ) )
return ;
2014-05-18 23:57:52 +00:00
if ( m_apPlayers [ ClientID ] )
m_apPlayers [ ClientID ] - > m_LastWhisperTo = VictimID ;
2013-10-18 09:42:35 +00:00
char aBuf [ 256 ] ;
2014-01-30 15:54:58 +00:00
if ( m_apPlayers [ ClientID ] & & m_apPlayers [ ClientID ] - > m_ClientVersion > = VERSION_DDNET_WHISPER )
2014-01-30 15:49:15 +00:00
{
CNetMsg_Sv_Chat Msg ;
Msg . m_Team = CHAT_WHISPER_SEND ;
Msg . m_ClientID = VictimID ;
Msg . m_pMessage = pMessage ;
2014-09-26 00:40:58 +00:00
if ( g_Config . m_SvDemoChat )
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL , ClientID ) ;
else
Server ( ) - > SendPackMsg ( & Msg , MSGFLAG_VITAL | MSGFLAG_NORECORD , ClientID ) ;
}
else
2014-01-30 15:49:15 +00:00
{
2014-09-22 14:16:47 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " [→ %s] %s " , Server ( ) - > ClientName ( VictimID ) , pMessage ) ;
2014-01-30 15:49:15 +00:00
SendChatTarget ( ClientID , aBuf ) ;
}
2013-08-09 13:04:20 +00:00
2014-01-30 15:54:58 +00:00
if ( m_apPlayers [ VictimID ] & & m_apPlayers [ VictimID ] - > m_ClientVersion > = VERSION_DDNET_WHISPER )
2014-01-30 15:49:15 +00:00
{
CNetMsg_Sv_Chat Msg2 ;
Msg2 . m_Team = CHAT_WHISPER_RECV ;
Msg2 . m_ClientID = ClientID ;
Msg2 . m_pMessage = pMessage ;
2014-09-26 00:40:58 +00:00
if ( g_Config . m_SvDemoChat )
Server ( ) - > SendPackMsg ( & Msg2 , MSGFLAG_VITAL , VictimID ) ;
else
Server ( ) - > SendPackMsg ( & Msg2 , MSGFLAG_VITAL | MSGFLAG_NORECORD , VictimID ) ;
}
else
2014-01-30 15:49:15 +00:00
{
2014-09-22 14:16:47 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " [← %s] %s " , Server ( ) - > ClientName ( ClientID ) , pMessage ) ;
2014-01-30 15:49:15 +00:00
SendChatTarget ( VictimID , aBuf ) ;
}
2013-08-09 13:04:20 +00:00
}
2013-10-18 09:42:35 +00:00
void CGameContext : : Converse ( int ClientID , char * pStr )
{
CPlayer * pPlayer = m_apPlayers [ ClientID ] ;
if ( ! pPlayer )
return ;
2014-04-23 22:43:49 +00:00
if ( ProcessSpamProtection ( ClientID ) )
return ;
2013-10-18 09:42:35 +00:00
if ( pPlayer - > m_LastWhisperTo < 0 )
SendChatTarget ( ClientID , " You do not have an ongoing conversation. Whisper to someone to start one " ) ;
else
{
WhisperID ( ClientID , pPlayer - > m_LastWhisperTo , pStr ) ;
}
}
2013-12-31 05:13:57 +00:00
2017-03-21 10:24:44 +00:00
void CGameContext : : List ( int ClientID , const char * pFilter )
2013-12-31 05:13:57 +00:00
{
2017-03-21 10:24:44 +00:00
int Total = 0 ;
char aBuf [ 256 ] ;
int Bufcnt = 0 ;
if ( pFilter [ 0 ] )
str_format ( aBuf , sizeof ( aBuf ) , " Listing players with \" %s \" in name: " , pFilter ) ;
2013-12-31 05:13:57 +00:00
else
2017-07-26 01:58:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " Listing all players: " ) ;
2017-03-21 10:24:44 +00:00
SendChatTarget ( ClientID , aBuf ) ;
2013-12-31 05:13:57 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] )
{
2017-03-21 10:24:44 +00:00
Total + + ;
const char * pName = Server ( ) - > ClientName ( i ) ;
if ( str_find_nocase ( pName , pFilter ) = = NULL )
2013-12-31 05:13:57 +00:00
continue ;
2017-03-21 10:24:44 +00:00
if ( Bufcnt + str_length ( pName ) + 4 > 256 )
2013-12-31 05:13:57 +00:00
{
2017-03-21 10:24:44 +00:00
SendChatTarget ( ClientID , aBuf ) ;
Bufcnt = 0 ;
2013-12-31 05:13:57 +00:00
}
2017-03-21 10:24:44 +00:00
if ( Bufcnt ! = 0 )
2013-12-31 05:13:57 +00:00
{
2017-03-21 10:24:44 +00:00
str_format ( & aBuf [ Bufcnt ] , sizeof ( aBuf ) - Bufcnt , " , %s " , pName ) ;
Bufcnt + = 2 + str_length ( pName ) ;
2013-12-31 05:13:57 +00:00
}
else
{
2017-03-21 10:24:44 +00:00
str_format ( & aBuf [ Bufcnt ] , sizeof ( aBuf ) - Bufcnt , " %s " , pName ) ;
Bufcnt + = str_length ( pName ) ;
2013-12-31 05:13:57 +00:00
}
}
}
2017-03-21 10:24:44 +00:00
if ( Bufcnt ! = 0 )
SendChatTarget ( ClientID , aBuf ) ;
str_format ( aBuf , sizeof ( aBuf ) , " %d players online " , Total ) ;
SendChatTarget ( ClientID , aBuf ) ;
2013-12-31 05:13:57 +00:00
}
2017-06-06 05:31:56 +00:00
int CGameContext : : GetClientVersion ( int ClientID ) {
return m_apPlayers [ ClientID ]
? m_apPlayers [ ClientID ] - > m_ClientVersion
: 0 ;
}
void CGameContext : : SetClientVersion ( int ClientID , int Version ) {
if ( ! m_apPlayers [ ClientID ] ) {
return ;
}
m_apPlayers [ ClientID ] - > m_ClientVersion = Version ;
}
2018-01-05 11:04:06 +00:00
bool CGameContext : : PlayerModerating ( )
{
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( m_apPlayers [ i ] & & m_apPlayers [ i ] - > m_Moderating )
return true ;
}
return false ;
}