2004-08-23 00:15:46 +00:00
# include "quakedef.h"
2005-08-03 23:14:59 +00:00
# include <ctype.h>
2005-08-26 22:56:51 +00:00
# ifdef _WIN32
2014-03-30 08:55:06 +00:00
# include "winquake.h"
2005-08-26 22:56:51 +00:00
# endif
2005-08-03 23:14:59 +00:00
typedef struct f_modified_s {
char name [ MAX_QPATH ] ;
qboolean ismodified ;
struct f_modified_s * next ;
} f_modified_t ;
2007-09-17 20:35:39 +00:00
static f_modified_t * f_modified_list ;
2005-08-03 23:14:59 +00:00
qboolean care_f_modified ;
qboolean f_modified_particles ;
2015-06-26 13:29:40 +00:00
static void QDECL rulesetcallback ( cvar_t * var , char * oldval )
2015-06-26 13:21:04 +00:00
{
Validation_Apply_Ruleset ( ) ;
}
2005-08-03 23:14:59 +00:00
2016-09-08 19:04:35 +00:00
cvar_t allow_f_version = CVAR ( " allow_f_version " , " 1 " ) ;
cvar_t allow_f_server = CVAR ( " allow_f_server " , " 1 " ) ;
cvar_t allow_f_modified = CVAR ( " allow_f_modified " , " 1 " ) ;
cvar_t allow_f_skins = CVAR ( " allow_f_skins " , " 1 " ) ;
cvar_t allow_f_ruleset = CVAR ( " allow_f_ruleset " , " 1 " ) ;
cvar_t allow_f_scripts = CVAR ( " allow_f_scripts " , " 1 " ) ;
cvar_t allow_f_fakeshaft = CVAR ( " allow_f_fakeshaft " , " 1 " ) ;
cvar_t allow_f_system = CVAR ( " allow_f_system " , " 0 " ) ;
cvar_t allow_f_cmdline = CVAR ( " allow_f_cmdline " , " 0 " ) ;
cvar_t auth_validateclients = CVAR ( " auth_validateclients " , " 1 " ) ;
2015-06-26 13:21:04 +00:00
cvar_t ruleset = CVARC ( " ruleset " , " none " , rulesetcallback ) ;
2005-08-03 23:14:59 +00:00
# define SECURITY_INIT_BAD_CHECKSUM 1
# define SECURITY_INIT_BAD_VERSION 2
# define SECURITY_INIT_ERROR 3
# define SECURITY_INIT_NOPROC 4
typedef struct signed_buffer_s {
qbyte * buf ;
unsigned long size ;
} signed_buffer_t ;
2007-09-17 20:35:39 +00:00
typedef signed_buffer_t * ( * Security_Verify_Response_t ) ( int playernum , unsigned char * , char * userinfo , char * serverinfo ) ;
2005-08-03 23:14:59 +00:00
typedef int ( * Security_Init_t ) ( char * ) ;
2007-09-17 20:35:39 +00:00
typedef signed_buffer_t * ( * Security_Generate_Crc_t ) ( int playernum , char * userinfo , char * serverinfo ) ;
2005-08-03 23:14:59 +00:00
typedef signed_buffer_t * ( * Security_IsModelModified_t ) ( char * , int , qbyte * , int ) ;
typedef void ( * Security_Supported_Binaries_t ) ( void * ) ;
typedef void ( * Security_Shutdown_t ) ( void ) ;
2007-09-17 20:35:39 +00:00
static Security_Verify_Response_t Security_Verify_Response ;
static Security_Init_t Security_Init ;
static Security_Generate_Crc_t Security_Generate_Crc ;
static Security_IsModelModified_t Security_IsModelModified ;
static Security_Supported_Binaries_t Security_Supported_Binaries ;
static Security_Shutdown_t Security_Shutdown ;
2005-08-03 23:14:59 +00:00
2014-03-30 08:55:06 +00:00
#if 0 //def _WIN32
2007-09-17 20:35:39 +00:00
static void * secmodule ;
2011-01-29 21:01:40 +00:00
# endif
2005-08-03 23:14:59 +00:00
2007-09-17 20:35:39 +00:00
static void Validation_Version ( void )
2005-08-03 23:14:59 +00:00
{
char sr [ 256 ] ;
2007-09-17 20:35:39 +00:00
char * s = sr ;
char authbuf [ 256 ] ;
2008-11-09 22:29:28 +00:00
char * auth = authbuf ;
2005-08-03 23:14:59 +00:00
2014-10-05 20:04:11 +00:00
extern cvar_t r_drawflat ;
2005-09-14 04:15:00 +00:00
2013-10-08 14:28:11 +00:00
//print certain allowed 'cheat' options.
//realtime lighting (shadows can show around corners)
//drawflat is just lame
//24bits can be considered eeeevil, by some.
# ifdef RTLIGHTS
if ( r_shadow_realtime_world . ival )
* s + + = ' W ' ;
else if ( r_shadow_realtime_dlight . ival )
* s + + = ' S ' ;
2005-08-03 23:14:59 +00:00
# endif
2016-09-08 19:04:35 +00:00
if ( r_drawflat . ival | | r_lightmap . ival )
2013-10-08 14:28:11 +00:00
* s + + = ' F ' ;
if ( gl_load24bit . ival )
* s + + = ' H ' ;
2005-09-14 04:15:00 +00:00
2007-09-17 20:35:39 +00:00
* s = ' \0 ' ;
2009-11-04 21:16:50 +00:00
if ( ! allow_f_version . ival )
2005-09-14 04:15:00 +00:00
return ; //suppress it
if ( Security_Generate_Crc )
2005-08-03 23:14:59 +00:00
{
signed_buffer_t * resp ;
2013-06-23 02:17:02 +00:00
resp = Security_Generate_Crc ( cl . playerview [ 0 ] . playernum , cl . players [ cl . playerview [ 0 ] . playernum ] . userinfo , cl . serverinfo ) ;
2007-09-17 20:35:39 +00:00
if ( ! resp | | ! resp - > buf )
auth = " " ;
else
Q_snprintfz ( auth , sizeof ( authbuf ) , " crc: %s " , resp - > buf ) ;
2005-08-03 23:14:59 +00:00
}
2007-09-17 20:35:39 +00:00
else
auth = " " ;
2005-08-03 23:14:59 +00:00
if ( * sr )
2011-03-30 15:17:55 +00:00
Cbuf_AddText ( va ( " say %s " PLATFORM " /%s/%s%s \n " , version_string ( ) , q_renderername , sr , auth ) , RESTRICT_RCON ) ;
2005-08-03 23:14:59 +00:00
else
2011-03-30 15:17:55 +00:00
Cbuf_AddText ( va ( " say %s " PLATFORM " /%s%s \n " , version_string ( ) , q_renderername , auth ) , RESTRICT_RCON ) ;
2005-08-03 23:14:59 +00:00
}
void Validation_CheckIfResponse ( char * text )
{
//client name, version type(os-renderer where it matters, os/renderer where renderer doesn't), 12 char hex crc
int f_query_client ;
int i ;
char * crc ;
char * versionstring ;
if ( ! Security_Verify_Response )
return ; //valid or not, we can't check it.
2009-11-04 21:16:50 +00:00
if ( ! auth_validateclients . ival )
2005-08-03 23:14:59 +00:00
return ;
//do the parsing.
{
char * comp ;
int namelen ;
for ( crc = text + strlen ( text ) - 1 ; crc > text ; crc - - )
if ( ( unsigned ) * crc > ' ' )
break ;
//find the crc.
for ( i = 0 ; i < 29 ; i + + )
{
if ( crc < = text )
return ; //not enough chars.
if ( ( unsigned ) crc [ - 1 ] < = ' ' )
break ;
crc - - ;
}
//we now want 3 string seperated tokens, so the first starts at the fourth found ' ' + 1
i = 7 ;
for ( comp = crc - 1 ; ; comp - - )
{
if ( comp < text )
return ;
if ( * comp = = ' ' )
{
i - - ;
if ( ! i )
break ;
}
}
versionstring = comp + 1 ;
if ( comp < = text )
return ; //not enough space for the 'name:'
if ( * ( comp - 1 ) ! = ' : ' )
return ; //whoops. not a say.
namelen = comp - text - 1 ;
2013-10-29 17:38:22 +00:00
for ( f_query_client = 0 ; f_query_client < cl . allocated_client_slots ; f_query_client + + )
2005-08-03 23:14:59 +00:00
{
if ( strlen ( cl . players [ f_query_client ] . name ) = = namelen )
if ( ! strncmp ( cl . players [ f_query_client ] . name , text , namelen ) )
break ;
}
2013-10-29 17:38:22 +00:00
if ( f_query_client = = cl . allocated_client_slots )
2005-08-03 23:14:59 +00:00
return ; //looks like a validation, but it's not from a known client.
}
2007-02-23 00:21:33 +00:00
{
2014-10-05 20:04:11 +00:00
char * match = DISTRIBUTION " v " ;
2007-02-23 00:21:33 +00:00
if ( strncmp ( versionstring , match , strlen ( match ) ) )
return ; //this is not us
}
2005-08-03 23:14:59 +00:00
//now do the validation
{
signed_buffer_t * resp ;
2007-09-17 20:35:39 +00:00
resp = Security_Verify_Response ( f_query_client , crc , cl . players [ f_query_client ] . userinfo , cl . serverinfo ) ;
2005-08-03 23:14:59 +00:00
if ( resp & & resp - > size & & * resp - > buf )
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_NOTICE " Authentication Successful. \n " ) ;
2005-08-03 23:14:59 +00:00
else // if (!resp)
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " AUTHENTICATION FAILED. \n " ) ;
2005-08-03 23:14:59 +00:00
}
}
2007-09-17 20:35:39 +00:00
void InitValidation ( void )
2005-08-03 23:14:59 +00:00
{
Cvar_Register ( & allow_f_version , " Authentication " ) ;
Cvar_Register ( & allow_f_server , " Authentication " ) ;
Cvar_Register ( & allow_f_modified , " Authentication " ) ;
Cvar_Register ( & allow_f_skins , " Authentication " ) ;
2007-09-17 20:35:39 +00:00
Cvar_Register ( & allow_f_ruleset , " Authentication " ) ;
Cvar_Register ( & allow_f_fakeshaft , " Authentication " ) ;
Cvar_Register ( & allow_f_scripts , " Authentication " ) ;
Cvar_Register ( & allow_f_system , " Authentication " ) ;
Cvar_Register ( & allow_f_cmdline , " Authentication " ) ;
Cvar_Register ( & ruleset , " Authentication " ) ;
2005-08-03 23:14:59 +00:00
2014-03-30 08:55:06 +00:00
#if 0 //def _WIN32
2005-08-03 23:14:59 +00:00
secmodule = LoadLibrary ( " fteqw-security.dll " ) ;
if ( secmodule )
{
Security_Verify_Response = ( void * ) GetProcAddress ( secmodule , " Security_Verify_Response " ) ;
Security_Init = ( void * ) GetProcAddress ( secmodule , " Security_Init " ) ;
Security_Generate_Crc = ( void * ) GetProcAddress ( secmodule , " Security_Generate_Crc " ) ;
Security_IsModelModified = ( void * ) GetProcAddress ( secmodule , " Security_IsModelModified " ) ;
Security_Supported_Binaries = ( void * ) GetProcAddress ( secmodule , " Security_Supported_Binaries " ) ;
Security_Shutdown = ( void * ) GetProcAddress ( secmodule , " Security_Shutdown " ) ;
}
2005-08-04 12:56:15 +00:00
# endif
2005-08-03 23:14:59 +00:00
if ( Security_Init )
{
2011-03-30 15:17:55 +00:00
switch ( Security_Init ( va ( " %s %.2f %i " , DISTRIBUTION , 2.57 , version_number ( ) ) ) )
2005-08-03 23:14:59 +00:00
{
case SECURITY_INIT_BAD_CHECKSUM :
Con_Printf ( " Checksum failed. Security module does not support this build. Go upgrade it. \n " ) ;
break ;
case SECURITY_INIT_BAD_VERSION :
Con_Printf ( " Version failed. Security module does not support this version. Go upgrade. \n " ) ;
break ;
case SECURITY_INIT_ERROR :
Con_Printf ( " 'Generic' security error. Stop hacking. \n " ) ;
break ;
case SECURITY_INIT_NOPROC :
2007-09-17 20:35:39 +00:00
Con_Printf ( " /proc/* does not exist. You will need to upgrade/reconfigure your kernel. \n " ) ;
2005-08-03 23:14:59 +00:00
break ;
case 0 :
Cvar_Register ( & auth_validateclients , " Authentication " ) ;
return ;
}
2014-03-30 08:55:06 +00:00
#if 0 //def _WIN32
2005-08-03 23:14:59 +00:00
FreeLibrary ( secmodule ) ;
2005-08-04 12:56:15 +00:00
# endif
2005-08-03 23:14:59 +00:00
}
2007-09-17 20:35:39 +00:00
Security_Verify_Response = NULL ;
Security_Init = NULL ;
Security_Generate_Crc = NULL ;
Security_IsModelModified = NULL ;
Security_Supported_Binaries = NULL ;
Security_Shutdown = NULL ;
2005-08-03 23:14:59 +00:00
}
2007-09-17 20:35:39 +00:00
//////////////////////
//f_modified
2005-08-03 23:14:59 +00:00
void Validation_IncludeFile ( char * filename , char * file , int filelen )
{
}
2007-09-17 20:35:39 +00:00
static void Validation_FilesModified ( void )
2004-08-23 00:15:46 +00:00
{
2013-06-23 02:17:02 +00:00
Con_Printf ( " f_modified not implemented \n " ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
void Validation_FlushFileList ( void )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
f_modified_t * fm ;
while ( f_modified_list )
{
fm = f_modified_list - > next ;
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
Z_Free ( f_modified_list ) ;
f_modified_list = fm ;
}
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
/////////////////////////
//minor (codewise) responses
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
static void Validation_Server ( void )
2004-08-23 00:15:46 +00:00
{
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2011-10-27 15:46:36 +00:00
# ifdef warningmsg
# pragma warningmsg("is allowing the user to turn this off practical?..")
2007-09-22 18:16:59 +00:00
# endif
2009-11-04 21:16:50 +00:00
if ( ! allow_f_server . ival )
2007-09-17 20:35:39 +00:00
return ;
2013-05-03 04:28:08 +00:00
Cbuf_AddText ( va ( " say server is %s \n " , NET_AdrToString ( adr , sizeof ( adr ) , & cls . netchan . remote_address ) ) , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
static void Validation_Skins ( void )
2004-08-23 00:15:46 +00:00
{
2012-01-24 04:24:14 +00:00
extern cvar_t r_fullbrightSkins , r_fb_models , ruleset_allow_fbmodels ;
2007-09-17 20:35:39 +00:00
int percent = r_fullbrightSkins . value * 100 ;
2004-08-23 00:15:46 +00:00
2009-11-04 21:16:50 +00:00
if ( ! allow_f_skins . ival )
2007-09-17 20:35:39 +00:00
return ;
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
RulesetLatch ( & r_fb_models ) ;
RulesetLatch ( & r_fullbrightSkins ) ;
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
if ( percent < 0 )
percent = 0 ;
if ( percent > cls . allow_fbskins * 100 )
percent = cls . allow_fbskins * 100 ;
if ( percent )
2012-01-24 04:24:14 +00:00
Cbuf_AddText ( va ( " say all player skins %i%% fullbright%s \n " , percent , ( r_fb_models . ival = = 1 & & ruleset_allow_fbmodels . ival ) ? " (non-player 100%%) " : ( r_fb_models . value ? " (plus luma) " : " " ) ) , RESTRICT_LOCAL ) ;
else if ( r_fb_models . ival = = 1 & & ruleset_allow_fbmodels . ival )
Cbuf_AddText ( " say non-player entities glow in the dark like a bright big cheat \n " , RESTRICT_LOCAL ) ;
2009-11-04 21:16:50 +00:00
else if ( r_fb_models . ival )
2007-09-17 20:35:39 +00:00
Cbuf_AddText ( " say luma textures only \n " , RESTRICT_LOCAL ) ;
else
Cbuf_AddText ( " say Only cheaters use full bright skins \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
static void Validation_Scripts ( void )
{ //subset of ruleset
2009-11-04 21:16:50 +00:00
if ( ! allow_f_scripts . ival )
2007-09-17 20:35:39 +00:00
return ;
2009-11-04 21:16:50 +00:00
if ( ruleset_allow_frj . ival )
2007-09-17 20:35:39 +00:00
Cbuf_AddText ( " say scripts are allowed \n " , RESTRICT_LOCAL ) ;
else
Cbuf_AddText ( " say scripts are capped \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
static void Validation_FakeShaft ( void )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
extern cvar_t cl_truelightning ;
2009-11-04 21:16:50 +00:00
if ( ! allow_f_fakeshaft . ival )
2007-09-17 20:35:39 +00:00
return ;
if ( cl_truelightning . value > 0.999 )
Cbuf_AddText ( " say fakeshaft on \n " , RESTRICT_LOCAL ) ;
else if ( cl_truelightning . value > 0 )
Cbuf_AddText ( va ( " say fakeshaft %.1f%% \n " , cl_truelightning . value ) , RESTRICT_LOCAL ) ;
else
Cbuf_AddText ( " say fakeshaft off \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
static void Validation_System ( void )
{ //subset of ruleset
2009-11-04 21:16:50 +00:00
if ( ! allow_f_system . ival )
2007-09-17 20:35:39 +00:00
return ;
Cbuf_AddText ( " say f_system not supported \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
static void Validation_CmdLine ( void )
2004-08-23 00:15:46 +00:00
{
2009-11-04 21:16:50 +00:00
if ( ! allow_f_cmdline . ival )
2007-09-17 20:35:39 +00:00
return ;
Cbuf_AddText ( " say f_cmdline not supported \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
//////////////////////
//rulesets
typedef struct {
char * rulename ;
char * rulevalue ;
} rulesetrule_t ;
typedef struct {
char * rulesetname ;
rulesetrule_t * rule ;
qboolean flagged ;
} ruleset_t ;
rulesetrule_t rulesetrules_strict [ ] = {
2015-06-30 14:05:45 +00:00
{ " ruleset_allow_shaders " , " 0 " } , /*users can potentially create all sorts of wallhacks or spiked models with this*/
2016-07-12 00:40:13 +00:00
{ " ruleset_allow_watervis " , " 0 " } , /*oh noes! users might be able to see underwater if they're already in said water. oh wait. what? why do we care, dude*/
2011-12-05 15:23:40 +00:00
{ " r_vertexlight " , " 0 " } ,
2007-09-17 20:35:39 +00:00
{ " ruleset_allow_playercount " , " 0 " } ,
{ " ruleset_allow_frj " , " 0 " } ,
{ " ruleset_allow_packet " , " 0 " } ,
{ " ruleset_allow_particle_lightning " , " 0 " } ,
2008-01-21 08:41:59 +00:00
{ " ruleset_allow_overlong_sounds " , " 0 " } ,
2007-09-17 20:35:39 +00:00
{ " ruleset_allow_larger_models " , " 0 " } ,
2008-02-01 15:21:14 +00:00
{ " ruleset_allow_modified_eyes " , " 0 " } ,
2014-03-30 08:55:06 +00:00
{ " ruleset_allow_sensitive_texture_replacements " , " 0 " } ,
2008-06-08 14:37:57 +00:00
{ " ruleset_allow_localvolume " , " 0 " } ,
2012-01-24 04:24:14 +00:00
{ " ruleset_allow_fbmodels " , " 0 " } ,
2015-06-30 14:05:45 +00:00
{ " scr_autoid_team " , " 0 " } , /*sort of a wallhack*/
2007-09-17 20:35:39 +00:00
{ " tp_disputablemacros " , " 0 " } ,
{ " cl_instantrotate " , " 0 " } ,
2011-10-27 15:46:36 +00:00
{ " v_projectionmode " , " 0 " } , /*no extended fovs*/
{ " r_shadow_realtime_world " , " 0 " } , /*static lighting can be used to cast shadows around corners*/
2015-07-03 02:07:41 +00:00
{ " ruleset_allow_in " , " 0 " } ,
{ " r_projection " , " 0 " } ,
2015-07-09 18:02:49 +00:00
{ " gl_shadeq1_name " , " * " } ,
2007-09-17 20:35:39 +00:00
{ NULL }
} ;
2008-01-21 08:41:59 +00:00
rulesetrule_t rulesetrules_nqr [ ] = {
2007-09-17 20:35:39 +00:00
{ " ruleset_allow_larger_models " , " 0 " } ,
{ " ruleset_allow_overlong_sounds " , " 0 " } ,
{ " ruleset_allow_particle_lightning " , " 0 " } ,
{ " ruleset_allow_packet " , " 0 " } ,
{ " ruleset_allow_frj " , " 0 " } ,
2008-02-01 15:21:14 +00:00
{ " ruleset_allow_modified_eyes " , " 0 " } ,
2014-03-30 08:55:06 +00:00
{ " ruleset_allow_sensitive_texture_replacements " , " 0 " } ,
2008-06-08 14:37:57 +00:00
{ " ruleset_allow_localvolume " , " 0 " } ,
2009-11-04 21:16:50 +00:00
{ " ruleset_allow_shaders " , " 0 " } ,
2012-01-24 04:24:14 +00:00
{ " ruleset_allow_fbmodels " , " 0 " } ,
2011-12-05 15:23:40 +00:00
{ " r_vertexlight " , " 0 " } ,
2011-10-27 15:46:36 +00:00
{ " v_projectionmode " , " 0 " } ,
2013-04-08 11:27:39 +00:00
{ " sbar_teamstatus " , " 0 " } ,
2015-07-03 02:07:41 +00:00
{ " ruleset_allow_in " , " 0 " } ,
{ " r_projection " , " 0 " } ,
2015-07-09 18:02:49 +00:00
{ " gl_shadeq1_name " , " * " } ,
2007-09-17 20:35:39 +00:00
{ NULL }
} ;
static ruleset_t rulesets [ ] =
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
{ " strict " , rulesetrules_strict } ,
2008-01-21 08:41:59 +00:00
{ " nqr " , rulesetrules_nqr } ,
2013-04-08 11:27:39 +00:00
//{"eql", rulesetrules_nqr},
2007-09-17 20:35:39 +00:00
{ NULL }
} ;
2004-08-23 00:15:46 +00:00
2015-06-26 13:21:04 +00:00
static qboolean ruleset_locked ;
2007-09-17 20:35:39 +00:00
void RulesetLatch ( cvar_t * cvar )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
cvar - > flags | = CVAR_RULESETLATCH ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
void Validation_DelatchRulesets ( void )
{ //game has come to an end, allow the ruleset to be changed
2015-06-26 13:21:04 +00:00
ruleset_locked = false ;
2011-12-05 15:23:40 +00:00
if ( Cvar_ApplyLatches ( CVAR_RULESETLATCH ) )
Con_DPrintf ( " Ruleset deactivated \n " ) ;
2004-08-23 00:15:46 +00:00
}
2009-04-01 22:03:56 +00:00
qboolean Validation_GetCurrentRulesetName ( char * rsnames , int resultbuflen , qboolean enforcechosenrulesets )
2007-09-17 20:35:39 +00:00
{ //this code is more complex than it needs to be
//this allows for the ruleset code to print a ruleset name that is applied via the cvars, but not directly named by the user
cvar_t * var ;
ruleset_t * rs ;
2004-08-23 00:15:46 +00:00
int i ;
2009-04-01 22:03:56 +00:00
2015-06-26 13:21:04 +00:00
if ( enforcechosenrulesets )
ruleset_locked = true ;
2007-09-17 20:35:39 +00:00
rs = rulesets ;
* rsnames = ' \0 ' ;
for ( rs = rulesets ; rs - > rulesetname ; rs + + )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
rs - > flagged = false ;
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
for ( i = 0 ; rs - > rule [ i ] . rulename ; i + + )
{
var = Cvar_FindVar ( rs - > rule [ i ] . rulename ) ;
if ( ! var ) //sw rendering?
continue ;
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
if ( strcmp ( var - > string , rs - > rule [ i ] . rulevalue ) )
2008-01-21 08:41:59 +00:00
{
Con_DPrintf ( " ruleset \" %s \" requires \" %s \" to be \" %s \" \n " , rs - > rulesetname , rs - > rule [ i ] . rulename , rs - > rule [ i ] . rulevalue ) ;
2007-09-17 20:35:39 +00:00
break ; //current settings don't match
2008-01-21 08:41:59 +00:00
}
2007-09-17 20:35:39 +00:00
}
if ( ! rs - > rule [ i ] . rulename )
{
if ( * rsnames )
{
2009-04-01 22:03:56 +00:00
Q_strncatz ( rsnames , " , " , resultbuflen ) ;
2007-09-17 20:35:39 +00:00
}
2009-04-01 22:03:56 +00:00
Q_strncatz ( rsnames , rs - > rulesetname , resultbuflen ) ;
2007-09-17 20:35:39 +00:00
rs - > flagged = true ;
}
}
if ( * rsnames )
{
2009-04-01 22:03:56 +00:00
//as we'll be telling the other players what rules we're playing by, we'd best stick to them
if ( enforcechosenrulesets )
2007-09-17 20:35:39 +00:00
{
2009-04-01 22:03:56 +00:00
for ( rs = rulesets ; rs - > rulesetname ; rs + + )
2007-09-17 20:35:39 +00:00
{
2009-04-01 22:03:56 +00:00
if ( ! rs - > flagged )
2007-09-17 20:35:39 +00:00
continue ;
2009-04-01 22:03:56 +00:00
for ( i = 0 ; rs - > rule [ i ] . rulename ; i + + )
{
var = Cvar_FindVar ( rs - > rule [ i ] . rulename ) ;
if ( ! var )
continue ;
RulesetLatch ( var ) ; //set the latched flag
}
2007-09-17 20:35:39 +00:00
}
}
2009-04-01 22:03:56 +00:00
return true ;
2007-09-17 20:35:39 +00:00
}
2009-04-01 22:03:56 +00:00
else
return false ;
}
void Validation_OldRuleset ( void )
{
char rsnames [ 1024 ] ;
if ( Validation_GetCurrentRulesetName ( rsnames , sizeof ( rsnames ) , true ) )
Cbuf_AddText ( va ( " say Ruleset: %s \n " , rsnames ) , RESTRICT_LOCAL ) ;
2007-09-17 20:35:39 +00:00
else
Cbuf_AddText ( " say No specific ruleset \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
2009-04-01 22:03:56 +00:00
void Validation_AllChecks ( void )
{
char servername [ 22 ] ;
char playername [ 16 ] ;
2011-03-30 15:17:55 +00:00
char * enginebuild = version_string ( ) ;
2013-06-23 02:17:02 +00:00
char localpnamelen = strlen ( cl . players [ cl . playerview [ 0 ] . playernum ] . name ) ;
2009-04-01 22:03:56 +00:00
char ruleset [ 1024 ] ;
//figure out the padding for the player's name.
if ( localpnamelen > = 15 )
playername [ 0 ] = 0 ;
else
{
2015-06-26 13:21:04 +00:00
//pad the left side to compensate for the player name prefix the server will add in the final svc_print
memset ( playername , ' ' , 15 - localpnamelen ) ;
2009-04-01 22:03:56 +00:00
playername [ 15 - localpnamelen ] = 0 ;
}
//get the current server address
2013-05-03 04:28:08 +00:00
NET_AdrToString ( servername , sizeof ( servername ) , & cls . netchan . remote_address ) ;
2009-04-01 22:03:56 +00:00
//get the ruleset names
if ( ! Validation_GetCurrentRulesetName ( ruleset , sizeof ( ruleset ) , true ) )
Q_strncpyz ( ruleset , " no ruleset " , sizeof ( ruleset ) ) ;
//now send it
CL_SendClientCommand ( true , " say \" %s%21s " " %16s %s \" " , playername , servername , enginebuild , ruleset ) ;
}
2007-09-17 20:35:39 +00:00
void Validation_Apply_Ruleset ( void )
{ //rulesets are applied when the client first gets a connection to the server
ruleset_t * rs ;
rulesetrule_t * rule ;
cvar_t * var ;
int i ;
2015-06-12 14:44:50 +00:00
char * rulesetname = ruleset . string ;
2015-06-26 13:21:04 +00:00
if ( ruleset_locked )
{
if ( ruleset . modified )
{
Con_Printf ( " Cannot change rulesets after the current ruleset has been announced \n " ) ;
ruleset . modified = false ;
}
return ;
}
ruleset . modified = false ;
2015-06-12 14:44:50 +00:00
if ( ! strcmp ( rulesetname , " smackdown " ) ) //officially, smackdown cannot authorise this, thus we do not use that name. however, imported configs tend to piss people off.
rulesetname = " strict " ;
2004-08-23 00:15:46 +00:00
2015-06-12 14:44:50 +00:00
if ( ! * rulesetname | | ! strcmp ( rulesetname , " none " ) | | ! strcmp ( rulesetname , " default " ) )
2015-06-26 13:21:04 +00:00
{
if ( Cvar_ApplyLatches ( CVAR_RULESETLATCH ) )
Con_DPrintf ( " Ruleset deactivated \n " ) ;
2007-09-17 20:35:39 +00:00
return ; //no ruleset is set
2015-06-26 13:21:04 +00:00
}
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
for ( rs = rulesets ; rs - > rulesetname ; rs + + )
2004-08-23 00:15:46 +00:00
{
2015-06-12 14:44:50 +00:00
if ( ! stricmp ( rs - > rulesetname , rulesetname ) )
2007-09-17 20:35:39 +00:00
break ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
if ( ! rs - > rulesetname )
2004-08-23 00:15:46 +00:00
{
2015-06-12 14:44:50 +00:00
Con_Printf ( " Cannot apply ruleset %s - not recognised \n " , rulesetname ) ;
2015-06-26 13:21:04 +00:00
if ( Cvar_ApplyLatches ( CVAR_RULESETLATCH ) )
Con_DPrintf ( " Ruleset deactivated \n " ) ;
2007-09-17 20:35:39 +00:00
return ;
}
for ( rule = rs - > rule ; rule - > rulename ; rule + + )
{
for ( i = 0 ; rs - > rule [ i ] . rulename ; i + + )
{
var = Cvar_FindVar ( rs - > rule [ i ] . rulename ) ;
if ( ! var )
continue ;
if ( ! Cvar_ApplyLatchFlag ( var , rs - > rule [ i ] . rulevalue , CVAR_RULESETLATCH ) )
{
Con_Printf ( " Failed to apply ruleset %s due to cvar %s \n " , rs - > rulesetname , var - > name ) ;
break ;
}
}
2004-08-23 00:15:46 +00:00
}
2005-11-26 03:02:55 +00:00
2007-09-17 20:35:39 +00:00
Con_DPrintf ( " Ruleset set to %s \n " , rs - > rulesetname ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
//////////////////////
2004-08-23 00:15:46 +00:00
2007-09-17 20:35:39 +00:00
void Validation_Auto_Response ( int playernum , char * s )
{
static float versionresponsetime ;
static float modifiedresponsetime ;
static float skinsresponsetime ;
static float serverresponsetime ;
static float rulesetresponsetime ;
static float systemresponsetime ;
static float fakeshaftresponsetime ;
static float cmdlineresponsetime ;
static float scriptsresponsetime ;
2017-01-24 10:27:39 +00:00
//quakeworld tends to use f_*
//netquake uses the slightly more guessable q_* form
if ( ! strncmp ( s , " f_ " , 2 ) )
s + = 2 ;
else if ( ! strncmp ( s , " q_ " , 2 ) )
s + = 2 ;
else
return ;
if ( ! strncmp ( s , " version " , 7 ) & & versionresponsetime < Sys_DoubleTime ( ) ) //respond to it.
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_Version ( ) ;
versionresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2007-09-17 20:35:39 +00:00
else if ( cl . spectator )
return ;
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " server " , 6 ) & & serverresponsetime < Sys_DoubleTime ( ) ) //respond to it.
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_Server ( ) ;
serverresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " system " , 6 ) & & systemresponsetime < Sys_DoubleTime ( ) )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_System ( ) ;
systemresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " cmdline " , 7 ) & & cmdlineresponsetime < Sys_DoubleTime ( ) )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_CmdLine ( ) ;
cmdlineresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " fakeshaft " , 9 ) & & fakeshaftresponsetime < Sys_DoubleTime ( ) )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_FakeShaft ( ) ;
fakeshaftresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " modified " , 8 ) & & modifiedresponsetime < Sys_DoubleTime ( ) ) //respond to it.
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_FilesModified ( ) ;
modifiedresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " scripts " , 7 ) & & scriptsresponsetime < Sys_DoubleTime ( ) )
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_Scripts ( ) ;
scriptsresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " skins " , 5 ) & & skinsresponsetime < Sys_DoubleTime ( ) ) //respond to it.
2004-08-23 00:15:46 +00:00
{
2007-09-17 20:35:39 +00:00
Validation_Skins ( ) ;
skinsresponsetime = Sys_DoubleTime ( ) + 5 ;
2004-08-23 00:15:46 +00:00
}
2017-01-24 10:27:39 +00:00
else if ( ! strncmp ( s , " ruleset " , 7 ) & & rulesetresponsetime < Sys_DoubleTime ( ) )
2005-08-03 23:14:59 +00:00
{
2009-03-03 01:52:30 +00:00
if ( 1 )
Validation_AllChecks ( ) ;
else
Validation_OldRuleset ( ) ;
2007-09-17 20:35:39 +00:00
rulesetresponsetime = Sys_DoubleTime ( ) + 5 ;
2005-08-03 23:14:59 +00:00
}
}