2019-03-02 15:17:41 +01:00
# pragma semicolon 1
# define DEBUG
# define PLUGIN_AUTHOR "jenz"
2019-07-23 20:53:06 +02:00
# define PLUGIN_VERSION "1.5"
2019-03-02 15:17:41 +01:00
# define g_dLength 256
# define g_dIndex 65
# include <sourcemod>
# include <colorvariables>
# include <unloze_zones>
# include <unloze_racetimer_specialmaps>
# include <unloze_racetimer_antizones>
# include <cstrike>
# include <sdktools>
# pragma newdecls required
char g_cMapname [ g_dLength ] ;
char g_cSpecialMapStart [ g_dLength ] ;
char g_cSpecialMapEnd [ g_dLength ] ;
static char g_sConfigzones [ PLATFORM_MAX_PATH ] ;
2019-07-23 20:53:06 +02:00
int g_iRoundMinutes ;
2019-03-02 15:17:41 +01:00
float g_fRoundSeconds ;
2019-07-23 20:53:06 +02:00
int g_iMinutesIndividual [ MAXPLAYERS + 1 ] ;
2019-03-02 15:17:41 +01:00
float g_fSecondsIndividual [ MAXPLAYERS + 1 ] ;
float g_fRecordSeconds [ g_dIndex + 1 ] [ 100 ] ;
2019-07-23 20:53:06 +02:00
float g_fClientVectors [ MAXPLAYERS + 1 ] [ 3 ] ;
2019-03-02 15:17:41 +01:00
int g_iRecordMinutes [ g_dIndex + 1 ] [ 100 ] ;
2019-07-23 20:53:06 +02:00
int g_iClientFrames [ MAXPLAYERS + 1 ] ;
int g_iClientSpeedInterval [ MAXPLAYERS + 1 ] ;
2019-03-02 15:17:41 +01:00
//100 because we have a total of 53 race zones right now
//testing
int g_iClientStage [ MAXPLAYERS + 1 ] ;
int g_iClientChecking [ MAXPLAYERS + 1 ] ;
bool g_bDisplaySpecial ;
2019-07-23 20:53:06 +02:00
bool g_bHumansAllowedTime [ MAXPLAYERS + 1 ] ;
2019-07-24 00:43:06 +02:00
bool g_bHideTimer [ MAXPLAYERS + 1 ] ;
2019-03-02 15:17:41 +01:00
Database g_dDatabase ;
2019-07-23 20:53:06 +02:00
Handle hText ;
2019-03-02 15:17:41 +01:00
public Plugin myinfo =
{
name = " UNLOZE_racetimer_css " ,
author = PLUGIN_AUTHOR ,
description = " tracers times on race maps " ,
version = PLUGIN_VERSION ,
url = " www.unloze.com "
} ;
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart ( )
{
//cmds
RegConsoleCmd ( " sm_toptime " , cmd_timerCheckTop , " checking top 10 " ) ;
RegConsoleCmd ( " sm_mytime " , cmd_timerCheckSelf , " checking your personal time " ) ;
RegConsoleCmd ( " sm_stages " , cmd_timerCheckStage , " Checking race stages " ) ;
2019-07-24 00:43:06 +02:00
RegConsoleCmd ( " sm_hidetimer " , cmd_hideTimerHUD , " Hides timer HUD " ) ;
2019-03-02 15:17:41 +01:00
//hooks
HookEvent ( " round_start " , Event_RoundStart , EventHookMode_PostNoCopy ) ;
2019-07-23 20:53:06 +02:00
//HUD
hText = CreateHudSynchronizer ( ) ;
}
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnMapStart ( )
{
//mysql placed here just in case somebody wants to reset database without having to reload plugin
g_bDisplaySpecial = unloze_gBSpecialMapDisplay ( ) ;
SQL_StartConnection ( ) ;
GetCurrentMap ( g_cMapname , sizeof ( g_cMapname ) ) ;
CreateTimer ( 0.1 , Timer_CountdownRace , INVALID_HANDLE , TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE ) ;
startTimer ( ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-07-23 20:53:06 +02:00
public void OnPluginEnd ( )
{
CloseHandle ( hText ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-03-02 15:17:41 +01:00
public void startTimer ( )
{
char line [ g_dLength ] ;
Handle zonefile = INVALID_HANDLE ;
BuildPath ( Path_SM , g_sConfigzones , sizeof ( g_sConfigzones ) , " configs/unloze_zones/%s.zones.txt " , g_cMapname ) ;
zonefile = OpenFile ( g_sConfigzones , " r " ) ;
if ( zonefile ! = INVALID_HANDLE )
{
while ( ! IsEndOfFile ( zonefile ) & & ReadFileLine ( zonefile , line , sizeof ( line ) ) )
{
if ( StrContains ( line , " ZONE_PREFIX_RACE " , false ) > - 1 | | g_bDisplaySpecial )
{
MYSQLCheckMapEntry ( ) ;
break ;
}
}
}
delete zonefile ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action Timer_CountdownRace ( Handle timer , any data )
{
g_fRoundSeconds + = 0.1 ;
if ( g_fRoundSeconds > = 60.0 )
{
2019-07-23 20:53:06 +02:00
g_iRoundMinutes + = 1 ;
2019-03-02 15:17:41 +01:00
g_fRoundSeconds = 0.0 ;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void Event_RoundStart ( Handle event , const char [ ] name , bool dontBroadcast )
{
2019-07-23 20:53:06 +02:00
g_iRoundMinutes = 0 ;
2019-03-02 15:17:41 +01:00
g_fRoundSeconds = 0.0 ;
for ( int i = 1 ; i < = MaxClients ; i + + )
if ( IsValidClient ( i ) )
{
MYSQLCheckRecord ( i ) ;
2019-07-23 20:53:06 +02:00
g_bHumansAllowedTime [ i ] = false ;
}
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientPostAdminCheck ( int client )
{
resetClient ( client ) ;
MYSQLCheckRecord ( client ) ;
2019-07-23 20:53:06 +02:00
g_bHumansAllowedTime [ client ] = false ;
2019-07-24 00:43:06 +02:00
g_bHideTimer [ client ] = false ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientDisconnect ( int client )
{
resetClient ( client ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void resetClient ( int client )
{
g_fSecondsIndividual [ client ] = 0.0 ;
2019-07-23 20:53:06 +02:00
g_iMinutesIndividual [ client ] = 0 ;
2019-03-02 15:17:41 +01:00
g_iClientChecking [ client ] = 0 ;
g_iClientStage [ client ] = 0 ;
2019-07-23 20:53:06 +02:00
g_bHumansAllowedTime [ client ] = false ;
resetClientVectors ( client ) ;
2019-07-24 00:43:06 +02:00
g_bHideTimer [ client ] = false ;
2019-07-23 20:53:06 +02:00
for ( int iterator = 0 ; iterator < 100 ; iterator + + )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
g_iRecordMinutes [ client ] [ iterator ] = 0 ;
g_fRecordSeconds [ client ] [ iterator ] = 0.0 ;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action OnPlayerRunCmd ( int client , int & buttons , int & impulse , float vel [ 3 ] , float angles [ 3 ] , int & weapon , int & subtype , int & cmdnum , int & tickcount , int & seed , int mouse [ 2 ] )
{
if ( g_bHumansAllowedTime [ client ] & & ( GetClientTeam ( client ) = = CS_TEAM_CT ) )
{
int frameCap = 11 ;
if ( g_iClientFrames [ client ] > = frameCap )
{
g_iClientFrames [ client ] = 0 ;
float clientVectors [ 3 ] ;
GetClientAbsOrigin ( client , clientVectors ) ;
if ( checkClientOrigin ( g_fClientVectors [ client ] , clientVectors , client , vel ) )
{
g_bHumansAllowedTime [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to potential teleport abuse " ) ;
return Plugin_Continue ;
}
int speedCheckerCap = 10 ;
if ( g_iClientSpeedInterval [ client ] > speedCheckerCap )
{
g_iClientSpeedInterval [ client ] = 0 ;
bool bNoclip = ( GetEntityMoveType ( client ) = = MOVETYPE_NOCLIP ) ;
if ( bNoclip )
{
g_bHumansAllowedTime [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to Noclip " ) ;
return Plugin_Continue ;
}
float speed = GetEntPropFloat ( client , Prop_Data , " m_flLaggedMovementValue " ) ;
if ( speed > 1.0 )
{
g_bHumansAllowedTime [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to modified run speed " ) ;
return Plugin_Continue ;
}
float client_gravity = GetEntityGravity ( client ) ;
ConVar gravity = FindConVar ( " sv_gravity " ) ;
float gravityFloat = gravity . FloatValue ;
2019-07-24 01:49:47 +02:00
int minimalPermitedGravity = 610 ;
2019-07-23 20:53:06 +02:00
//PrintToChat(client, "client_gravity: %f\ngravityFloat: %f", client_gravity, gravityFloat);
2019-07-24 01:49:47 +02:00
if ( ( client_gravity > 1.3 | | client_gravity < 0.8000 ) | | gravityFloat < minimalPermitedGravity )
2019-07-23 20:53:06 +02:00
{
g_bHumansAllowedTime [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to modified gravity " ) ;
return Plugin_Continue ;
}
}
g_fClientVectors [ client ] = clientVectors ;
{
2019-07-24 00:43:06 +02:00
if ( hText ! = INVALID_HANDLE & & ! g_bHideTimer [ client ] )
2019-07-23 20:53:06 +02:00
{
2019-07-24 00:43:06 +02:00
SetHudTextParams ( 0.35 , 0.85 , 0.1 , 125 , 255 , 255 , 85 ) ;
2019-07-23 20:53:06 +02:00
int l_iCalculateMins = CalculateValuesMinutes ( client ) ;
float l_fCalculateSecs = CalculateValues ( client ) ;
ShowSyncHudText ( client , hText , " %N Time: 0%i:%.1f \n Record: 0%i:%.1f \n Map: %s \n Stage: %i " , client , l_iCalculateMins ,
l_fCalculateSecs , g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] , g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] ,
g_cMapname , g_iClientStage [ client ] ) ;
}
}
g_iClientSpeedInterval [ client ] + + ;
}
g_iClientFrames [ client ] + + ;
2019-03-02 15:17:41 +01:00
}
2019-07-23 20:53:06 +02:00
return Plugin_Continue ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void resetClientVectors ( int client )
{
g_fClientVectors [ client ] [ 0 ] = 0.000000 ;
g_fClientVectors [ client ] [ 1 ] = 0.000000 ;
g_fClientVectors [ client ] [ 2 ] = 0.000000 ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public bool checkClientOrigin ( float oldVals [ 3 ] , float newVals [ 3 ] , int client , float vel [ 3 ] )
{
float zero = 0.000000 ;
int velocityCap = 600 ;
if ( ( oldVals [ 0 ] = = zero & & oldVals [ 1 ] = = zero & & oldVals [ 2 ] = = zero ) | | ( newVals [ 0 ] = = zero & & newVals [ 1 ] = = zero & & newVals [ 2 ] = = zero ) )
{
return false ;
}
float teleport_range = 50000.0 ;
float distance = GetVectorDistance ( oldVals , newVals , true ) ;
//PrintToChatAll("distance: %f", distance);
bool bInAir = ( GetEntPropEnt ( client , Prop_Send , " m_hGroundEntity " ) = = - 1 ) ;
if ( distance > teleport_range )
{
//PrintToChat(client, "distance: %f", distance);
//PrintToChat(client, "vel[0] %f \nvel[1] %f \nvel[2] %f", vel[0], vel[1], vel[2]);
if ( StrContains ( g_cMapname , " surf " , false ) ! = - 1 )
return false ;
if ( ( vel [ 0 ] > velocityCap | | vel [ 1 ] > velocityCap | | vel [ 2 ] > velocityCap ) & & bInAir )
return false ;
return true ;
}
return false ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void unloze_zoneEntry ( int client , char [ ] zone )
{
2019-07-23 20:53:06 +02:00
int zoneIndex = RetrieveZoneIndex ( zone ) ;
2019-03-02 15:17:41 +01:00
int l_iZoneCount = unloze_zoneCount ( ) ;
2019-07-23 20:53:06 +02:00
if ( ( ( GetClientTeam ( client ) = = CS_TEAM_CT & & g_bHumansAllowedTime [ client ] ) & & StrContains ( zone , " ZONE_PREFIX_RACE " ) > - 1 ) | | StrEqual ( zone , g_cSpecialMapEnd ) )
{
if ( l_iZoneCount < 2 )
2019-03-02 15:17:41 +01:00
{
g_iClientStage [ client ] = 0 ;
}
2019-07-23 20:53:06 +02:00
if ( g_iClientStage [ client ] = = ( zoneIndex / 2 ) | | l_iZoneCount < 2 )
2019-03-02 15:17:41 +01:00
{
FinishedStageRaceZone ( client ) ;
}
2019-07-23 20:53:06 +02:00
g_bHumansAllowedTime [ client ] = false ;
2019-03-02 15:17:41 +01:00
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void unloze_zoneLeave ( int client , char [ ] zone )
{
//only maps with multiple zones need ZONE_PREFIX_START
if ( ( ( GetClientTeam ( client ) = = CS_TEAM_CT ) & & StrContains ( zone , " ZONE_PREFIX_START " ) > - 1 ) | | StrEqual ( zone , g_cSpecialMapStart ) )
{
2019-07-23 20:53:06 +02:00
resetClientVectors ( client ) ;
2019-03-02 15:17:41 +01:00
g_fSecondsIndividual [ client ] = g_fRoundSeconds ;
2019-07-23 20:53:06 +02:00
g_iMinutesIndividual [ client ] = g_iRoundMinutes ;
float notRounded = float ( RetrieveZoneIndex ( zone ) ) ;
g_iClientStage [ client ] = RoundToCeil ( notRounded / 2 ) ;
g_bHumansAllowedTime [ client ] = true ;
CPrintToChat ( client , " Timer started for stage: %i " , g_iClientStage [ client ] ) ;
2019-03-02 15:17:41 +01:00
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void unloze_zoneCreated ( )
{
startTimer ( ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckIfSpecialRoundZones ( char [ ] resultstart , char [ ] resultend )
{
Format ( g_cSpecialMapStart , sizeof ( g_cSpecialMapStart ) , resultstart ) ;
Format ( g_cSpecialMapEnd , sizeof ( g_cSpecialMapEnd ) , resultend ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckifAntiZones ( int client , bool reset )
{
if ( reset )
{
//adds 30 mins and 30 seconds to a client because thats simple and very effective
g_fSecondsIndividual [ client ] = 30.0 ;
2019-07-23 20:53:06 +02:00
g_iMinutesIndividual [ client ] = 30 ;
2019-03-02 15:17:41 +01:00
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int RetrieveZoneIndex ( char [ ] zone )
{
//if you leave zone_2 you want the corresponding racezone to be zone_3
2019-07-23 20:53:06 +02:00
int iterator = strlen ( zone ) - 1 ;
2019-03-02 15:17:41 +01:00
char l_sZone [ g_dIndex ] ;
Format ( l_sZone , sizeof ( l_sZone ) , zone ) ;
2019-07-23 20:53:06 +02:00
while ( IsCharNumeric ( l_sZone [ iterator ] ) )
iterator - - ;
iterator + + ;
strcopy ( l_sZone , sizeof ( l_sZone ) , l_sZone [ iterator ] ) ;
return StringToInt ( l_sZone [ iterator ] ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void FinishedStageRaceZone ( int client )
{
int l_iZoneCount = unloze_zoneCount ( ) ;
2019-07-23 20:53:06 +02:00
int l_iCalculateMins ;
2019-03-02 15:17:41 +01:00
float l_fCalculateSecs ;
if ( g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] > 0 | | g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] > 0.0 )
CPrintToChat ( client , " Your record: 0%i:%.1f \n Command: !toptime !mytime !stages " , g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] , g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] ) ;
else
{
if ( l_iZoneCount < 2 )
2019-07-23 20:53:06 +02:00
sendMYSQL ( client , g_iRoundMinutes , g_fRoundSeconds , 0 , 0.0 , g_iClientStage [ client ] ) ;
2019-03-02 15:17:41 +01:00
else
{
2019-07-23 20:53:06 +02:00
l_iCalculateMins = CalculateValuesMinutes ( client ) ;
l_fCalculateSecs = CalculateValues ( client ) ;
sendMYSQL ( client , l_iCalculateMins , l_fCalculateSecs , 0 , 0.0 , g_iClientStage [ client ] ) ;
2019-03-02 15:17:41 +01:00
}
CPrintToChat ( client , " Updated timer " ) ;
}
if ( l_iZoneCount < 2 )
{
//no start zone, we use round time
2019-07-23 20:53:06 +02:00
CPrintToChat ( client , " {green}[UNLOZE] Client: %N Time: 0%i:%.1f " , client , g_iRoundMinutes , g_fRoundSeconds ) ;
if ( ( g_iRoundMinutes < g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] )
| | ( g_iRoundMinutes = = g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] & & g_fRoundSeconds < g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] ) )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
sendMYSQL ( client , g_iRoundMinutes , g_fRoundSeconds , g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] , g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] , g_iClientStage [ client ] ) ;
2019-03-02 15:17:41 +01:00
CPrintToChat ( client , " Updated timer " ) ;
}
}
else
{
//uses start zone, we use time when leaving start zone
2019-07-23 20:53:06 +02:00
l_iCalculateMins = CalculateValuesMinutes ( client ) ;
l_fCalculateSecs = CalculateValues ( client ) ;
2019-03-02 15:17:41 +01:00
//tricking ppl !hehe
2019-07-23 20:53:06 +02:00
CPrintToChat ( client , " {green}[UNLOZE] Stage: %i " , g_iClientStage [ client ] ) ;
CPrintToChat ( client , " {green}[UNLOZE] Client: %N Time: 0%i:%.1f " , client , l_iCalculateMins , l_fCalculateSecs ) ;
if ( ( l_iCalculateMins < g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] )
| | ( l_iCalculateMins = = g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] & & l_fCalculateSecs < g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] ) )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
sendMYSQL ( client , l_iCalculateMins , l_fCalculateSecs , g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] , g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] , g_iClientStage [ client ] ) ;
2019-03-02 15:17:41 +01:00
CPrintToChat ( client , " Updated timer " ) ;
}
}
//matching the message
MYSQLCheckRecord ( client ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-07-23 20:53:06 +02:00
public int CalculateValuesMinutes ( int client )
{
float l_fRoundSeconds = g_fRoundSeconds ;
float l_fRoundSecondsIndividual = g_fSecondsIndividual [ client ] ;
int l_iRoundMinutes = g_iRoundMinutes ;
int l_iRoundMinutesIndividual = g_iMinutesIndividual [ client ] ;
if ( l_iRoundMinutesIndividual > l_iRoundMinutes )
return 0 ;
l_iRoundMinutes = l_iRoundMinutes - l_iRoundMinutesIndividual ;
if ( l_fRoundSeconds < l_fRoundSecondsIndividual )
l_iRoundMinutes - - ;
return l_iRoundMinutes ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public float CalculateValues ( int client )
2019-03-02 15:17:41 +01:00
{
// 2:24 enter with roundtime 5:29 = 3:05
// 3:01 enter with roundtime 3:59 = 58 sec
//example roundtime is 5 mins 40 seconds, client entered at 4 mins and 50 seconds, so 50 sec race
float l_fRoundSeconds = g_fRoundSeconds ;
float l_fRoundSecondsIndividual = g_fSecondsIndividual [ client ] ;
float l_fSecAdd ;
2019-07-23 20:53:06 +02:00
if ( l_fRoundSeconds < l_fRoundSecondsIndividual )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
while ( l_fRoundSecondsIndividual < 60 )
{
l_fRoundSecondsIndividual + + ;
l_fSecAdd + + ;
}
float returnvalue = l_fSecAdd + l_fRoundSeconds ;
//PrintToChat(client, "returnvalue float: %f", returnvalue);
return returnvalue ;
2019-03-02 15:17:41 +01:00
}
else
{
2019-07-23 20:53:06 +02:00
float returnvalueminus = l_fRoundSeconds - l_fRoundSecondsIndividual ;
//PrintToChat(client, "returnvalueminus float: %f", returnvalueminus);
return returnvalueminus ;
2019-03-02 15:17:41 +01:00
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void MYSQLCheckMapEntry ( )
{
int l_iRaceCount ;
int l_iZoneCount = unloze_zoneCount ( ) ;
char sQuery [ g_dLength ] ;
char l_cZoneIndexName [ g_dIndex ] [ g_dLength ] ;
if ( l_iZoneCount < 2 )
{
Format ( sQuery , sizeof ( sQuery ) , " SELECT `%s` FROM `zetimer_table` LIMIT 1 " , g_cMapname ) ;
SQL_TQuery ( g_dDatabase , TqueryThreadCallback , sQuery ) ;
}
else
2019-07-23 20:53:06 +02:00
for ( int iterator = 0 ; iterator < = l_iZoneCount ; iterator + + )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
if ( IsCorrectZone ( iterator , l_cZoneIndexName [ iterator ] [ g_dLength - 1 ] , " ZONE_PREFIX_RACE " ) )
2019-03-02 15:17:41 +01:00
{
l_iRaceCount + + ;
Format ( sQuery , sizeof ( sQuery ) , " SELECT `%sS%i` FROM `zetimer_table` LIMIT 1 " , g_cMapname , l_iRaceCount ) ;
SQL_TQuery ( g_dDatabase , TqueryThreadCallback , sQuery ) ;
}
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void TqueryThreadCallback ( Handle owner , Handle rs , const char [ ] error , any data )
{
int l_iRaceCount ;
int l_iZoneCount = unloze_zoneCount ( ) ;
int client = 0 ;
float l_fRecordTotal ;
char sQuery [ g_dLength ] ;
char l_cZoneIndexName [ g_dIndex ] [ g_dLength ] ;
/ *
* the null check is for MYSQLCheckMapEntry and MYSQLCheckRecord to check if tables exist
* /
if ( rs = = null )
{
if ( l_iZoneCount = = 1 )
{
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table` ADD COLUMN `%s` DECIMAL(13,3) NOT NULL " , g_cMapname ) ;
SQL_FastQuery ( g_dDatabase , sQuery ) ;
}
else
{
//this might seem repetitive but one null check adds all required coloumns
2019-07-23 20:53:06 +02:00
for ( int iterator = 0 ; iterator < = l_iZoneCount ; iterator + + )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
if ( IsCorrectZone ( iterator , l_cZoneIndexName [ iterator ] [ g_dLength - 1 ] , " ZONE_PREFIX_RACE " ) )
2019-03-02 15:17:41 +01:00
{
l_iRaceCount + + ;
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table` ADD COLUMN `%sS%i` DECIMAL(13,3) NOT NULL " , g_cMapname , l_iRaceCount ) ;
SQL_FastQuery ( g_dDatabase , sQuery ) ;
}
}
}
return ;
}
if ( ! ( client = GetClientOfUserId ( data ) ) )
return ;
2019-07-23 20:53:06 +02:00
int rowsize = SQL_GetRowCount ( rs ) ;
if ( rowsize > 0 & & SQL_FetchRow ( rs ) )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
g_iClientStage [ client ] = 0 ;
int fieldSize = SQL_GetFieldCount ( rs ) ;
for ( int iterate = 0 ; iterate < fieldSize ; iterate + + )
{
l_fRecordTotal = SQL_FetchFloat ( rs , iterate ) ;
g_iClientStage [ client ] + + ;
g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] = ( RoundToFloor ( l_fRecordTotal ) ) ;
g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] = ( l_fRecordTotal - g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] ) * 100 ;
/ *
PrintToChat ( client , " g_iRecordMinutes[client][g_iClientStage[client]]: %i \n g_fRecordSeconds[client][g_iClientStage[client]] %f " ,
g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] , g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] ) ;
PrintToChat ( client , " g_iClientStage[client]: %i " , g_iClientStage [ client ] ) ;
* /
}
2019-03-02 15:17:41 +01:00
}
else
{
2019-07-23 20:53:06 +02:00
g_iRecordMinutes [ client ] [ g_iClientStage [ client ] ] = 0 ;
g_fRecordSeconds [ client ] [ g_iClientStage [ client ] ] = 0.0 ;
2019-03-02 15:17:41 +01:00
}
}
//----------------------------------------------------------------------------------------------------
// Purpose: TODO implement if needed
//----------------------------------------------------------------------------------------------------
public int GetTotalRaceZones ( )
{
int l_iZoneCount = unloze_zoneCount ( ) ;
char l_cIndexName [ g_dLength ] ;
int l_iCountRace ;
2019-07-23 20:53:06 +02:00
for ( int iterator = 0 ; iterator < l_iZoneCount ; iterator + + )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
ZoneNameBasedOnIndex ( iterator , l_cIndexName [ iterator ] ) ;
if ( StrContains ( l_cIndexName [ iterator ] , " ZONE_PREFIX_RACE " ) > - 1 )
2019-03-02 15:17:41 +01:00
l_iCountRace + + ;
}
return l_iCountRace ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-07-23 20:53:06 +02:00
public void sendMYSQL ( int client , int minutes , float seconds , int oldminutes , float oldseconds , int stage )
2019-03-02 15:17:41 +01:00
{
int l_iZoneCount = unloze_zoneCount ( ) ;
2019-07-23 20:53:06 +02:00
float l_fPlayerTime = float ( minutes ) ;
2019-03-02 15:17:41 +01:00
float l_fPlayerTimeOld ;
char sSID [ g_dIndex ] ;
char l_cClientName [ g_dIndex ] ;
char l_cStage [ 90 ] ;
char sQuery [ g_dLength ] ;
char sName [ MAX_NAME_LENGTH ] ;
GetClientAuthId ( client , AuthId_Steam2 , sSID , sizeof ( sSID ) ) ;
GetClientName ( client , sName , sizeof ( sName ) ) ;
int size2 = 2 * strlen ( sName ) + 1 ;
char [ ] sEscapedName = new char [ size2 + 1 ] ;
SQL_EscapeString ( g_dDatabase , sName , sEscapedName , size2 + 1 ) ;
Format ( l_cClientName , sizeof ( l_cClientName ) , sEscapedName ) ;
//STEAM_ID_STOP_IGNORING_RETVALS might be considered exploit?
2019-07-23 20:53:06 +02:00
if ( StrEqual ( sSID , " STEAM_ID_STOP_IGNORING_RETVALS " ) | | StrEqual ( sSID , " STEAM_ID_PENDING " ) )
2019-03-02 15:17:41 +01:00
return ;
l_fPlayerTime = l_fPlayerTime + ( seconds / 100 ) ;
if ( oldminutes ! = 0 | | oldseconds ! = 0.0 )
{
l_fPlayerTimeOld + = oldminutes ;
l_fPlayerTimeOld = l_fPlayerTimeOld + ( oldseconds / 100 ) ;
if ( l_iZoneCount > 1 )
Format ( l_cStage , sizeof ( l_cStage ) , " %sS%i " , g_cMapname , stage ) ;
else
Format ( l_cStage , sizeof ( l_cStage ) , " %s " , g_cMapname ) ;
}
if ( l_iZoneCount < 2 )
Format ( sQuery , sizeof ( sQuery ) , " INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%s`) VALUES ('%s', '%s', '%f') ON DUPLICATE KEY UPDATE `name` = '%s', `%s` = '%f' " , g_cMapname , sSID , l_cClientName , l_fPlayerTime , l_cClientName , g_cMapname , l_fPlayerTime ) ;
else
Format ( sQuery , sizeof ( sQuery ) , " INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%sS%i`) VALUES ('%s', '%s', '%f') ON DUPLICATE KEY UPDATE `name` = '%s', `%sS%i` = '%f' " , g_cMapname , stage , sSID , l_cClientName , l_fPlayerTime , l_cClientName , g_cMapname , stage , l_fPlayerTime ) ;
SQL_TQuery ( g_dDatabase , DummyCallbackSimple , sQuery ) ;
2019-07-23 20:53:06 +02:00
//PrintToChatAll("SEND MYSQL sQuery: %s", sQuery);
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void SQL_StartConnection ( )
{
char error [ g_dLength ] ;
if ( SQL_CheckConfig ( " racetimercss " ) )
g_dDatabase = SQL_Connect ( " racetimercss " , true , error , sizeof ( error ) ) ;
if ( g_dDatabase = = null )
{
CPrintToChatAll ( " {green}[UNLOZE] {white}Error! Could not connect to MYSQL-DB! " ) ;
}
//create tables
char sQuery [ g_dLength ] ;
Format ( sQuery , sizeof ( sQuery ) , " CREATE TABLE IF NOT EXISTS `zetimer_table` (`steam_auth` VARCHAR(254) NOT NULL, `name` VARCHAR(254) NOT NULL, PRIMARY KEY (`steam_auth`)) " ) ;
SQL_TQuery ( g_dDatabase , DummyCallbackSimple , sQuery ) ;
2019-07-23 20:53:06 +02:00
MYSQLCheckMapEntry ( ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void MYSQLCheckRecord ( int client )
{
char sSID [ g_dIndex ] ;
char sQuery [ g_dLength ] ;
2019-07-23 20:53:06 +02:00
int l_iZoneCount = unloze_zoneCount ( ) ;
//PrintToChat(client, "l_iZoneCount: %i", l_iZoneCount);
2019-03-02 15:17:41 +01:00
GetClientAuthId ( client , AuthId_Steam2 , sSID , sizeof ( sSID ) ) ;
2019-07-23 20:53:06 +02:00
StrCat ( sQuery , sizeof ( sQuery ) , " SELECT " ) ;
if ( l_iZoneCount > 1 )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
for ( int iterator = 0 ; iterator < l_iZoneCount / 2 ; iterator + + )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
if ( iterator > 0 )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
StrCat ( sQuery , sizeof ( sQuery ) , " , " ) ;
2019-03-02 15:17:41 +01:00
}
2019-07-23 20:53:06 +02:00
char mapstage [ g_dLength ] ;
Format ( mapstage , sizeof ( mapstage ) , " %sS%i " , g_cMapname , iterator + 1 ) ;
StrCat ( sQuery , sizeof ( sQuery ) , mapstage ) ;
2019-03-02 15:17:41 +01:00
}
2019-07-23 20:53:06 +02:00
} else { StrCat ( sQuery , sizeof ( sQuery ) , g_cMapname ) ; }
char endQuery [ g_dLength ] ;
Format ( endQuery , sizeof ( endQuery ) , " FROM `zetimer_table` WHERE steam_auth = '%s' " , sSID ) ;
StrCat ( sQuery , sizeof ( sQuery ) , endQuery ) ;
SQL_TQuery ( g_dDatabase , TqueryThreadCallback , sQuery , GetClientUserId ( client ) ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void DummyCallbackSimple ( Handle hOwner , Handle hChild , const char [ ] err , DataPack pack1 )
{
if ( hOwner = = null | | hChild = = null )
LogError ( " Query error. (%s) " , err ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action cmd_timerCheckTop ( int client , int args )
{
CheckTop ( client , 0 , 0 ) ;
return Plugin_Handled ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckTop ( int client , int index , int autismstate )
{
int l_iZoneCount = unloze_zoneCount ( ) ;
char sQuery [ g_dLength ] ;
2019-07-23 20:53:06 +02:00
//PrintToChatAll("checktop l_iZoneCount: %i", l_iZoneCount);
if ( l_iZoneCount < 1 )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
PrintToChat ( client , " No zones active on this map " ) ;
2019-03-02 15:17:41 +01:00
return ;
}
2019-07-23 20:53:06 +02:00
if ( ! autismstate )
2019-03-02 15:17:41 +01:00
{
CheckStagesOnMap ( client , 0 ) ;
return ;
}
2019-07-23 20:53:06 +02:00
//we have index now from menu selection
2019-03-02 15:17:41 +01:00
if ( l_iZoneCount < 2 )
Format ( sQuery , sizeof ( sQuery ) , " SELECT name, %s FROM `zetimer_table` WHERE %s > 0.000 ORDER BY %s ASC LIMIT 10 " , g_cMapname , g_cMapname , g_cMapname ) ;
else
Format ( sQuery , sizeof ( sQuery ) , " SELECT name, `%sS%i` FROM `zetimer_table` WHERE `%sS%i` > 0.000 ORDER BY `%sS%i` ASC LIMIT 10 " , g_cMapname , index , g_cMapname , index , g_cMapname , index ) ;
SQL_TQuery ( g_dDatabase , SQL_SelectTop_Callback , sQuery , GetClientUserId ( client ) ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void SQL_SelectTop_Callback ( Handle db , Handle results , const char [ ] error , any data )
{
int client = GetClientOfUserId ( data ) ;
int l_iMinutes ;
int l_iPosition ;
float l_fRecord ;
float l_iSeconds ;
//Player Name
char [ ] g_cPlayerName = new char [ MAX_NAME_LENGTH ] ;
char g_cContent [ g_dLength ] ;
if ( client = = 0 )
{
return ;
}
Menu menu = new Menu ( MenuHandler1 ) ;
menu . SetTitle ( " Maptimer: %s " , g_cMapname ) ;
while ( SQL_GetRowCount ( results ) > 0 & & SQL_FetchRow ( results ) )
{
l_iPosition + + ;
SQL_FetchString ( results , 0 , g_cPlayerName , MAX_NAME_LENGTH ) ;
l_fRecord = SQL_FetchFloat ( results , 1 ) ;
l_iMinutes = RoundToFloor ( l_fRecord ) ;
l_iSeconds = ( l_fRecord - l_iMinutes ) * 100 ;
Format ( g_cContent , sizeof ( g_cContent ) , " #%i: Time: 0%i:%.1f - %s " , l_iPosition , l_iMinutes , l_iSeconds , g_cPlayerName ) ;
menu . AddItem ( " -1 " , g_cContent , ITEMDRAW_DISABLED ) ;
}
if ( ! l_iPosition )
{
menu . AddItem ( " -1 " , " No results. Commands: !toptime !stages " , ITEMDRAW_DISABLED ) ;
}
menu . ExitButton = true ;
menu . Display ( client , 0 ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int MenuHandler1 ( Menu menu , MenuAction action , int param1 , int param2 )
{
if ( action = = MenuAction_End )
{
delete menu ;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-07-24 00:43:06 +02:00
public Action cmd_hideTimerHUD ( int client , int args )
{
if ( ! g_bHideTimer [ client ] )
{
g_bHideTimer [ client ] = true ;
PrintToChat ( client , " Disabled timer HUD " ) ;
} else { g_bHideTimer [ client ] = false ; PrintToChat ( client , " Enabled timer HUD " ) ; }
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-03-02 15:17:41 +01:00
public Action cmd_timerCheckStage ( int client , int args )
{
CheckStagesOnMap ( client , 0 ) ;
return Plugin_Handled ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckStagesOnMap ( int client , int state )
{
int l_iCount ;
int l_iZoneCount = unloze_zoneCount ( ) ;
Menu StageMenu = CreateMenu ( Stage_menu ) ;
char l_cZoneIndexName [ g_dIndex ] [ g_dLength ] ;
char l_cMenuContent [ g_dLength ] ;
if ( ! l_iZoneCount )
{
CPrintToChat ( client , " [UNLOZE] Map does not support racestage timer " ) ;
return ;
}
//state 0 == toptime, state 1 == own time
g_iClientChecking [ client ] = state ;
StageMenu . SetTitle ( " Stages on: %s " , g_cMapname ) ;
if ( g_bDisplaySpecial )
{
2019-07-23 20:53:06 +02:00
l_iCount + + ;
2019-03-02 15:17:41 +01:00
Format ( l_cMenuContent , sizeof ( l_cMenuContent ) , " Stage: %i " , l_iCount ) ;
StageMenu . AddItem ( " " , l_cMenuContent ) ;
}
else
2019-07-23 20:53:06 +02:00
{
for ( int Iterator = 0 ; Iterator < = l_iZoneCount ; Iterator + + )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
if ( IsCorrectZone ( Iterator , l_cZoneIndexName [ Iterator ] [ g_dLength - 1 ] , " ZONE_PREFIX_RACE " ) )
2019-03-02 15:17:41 +01:00
{
l_iCount + + ;
Format ( l_cMenuContent , sizeof ( l_cMenuContent ) , " Stage: %i " , l_iCount ) ;
StageMenu . AddItem ( " " , l_cMenuContent ) ;
}
}
2019-07-23 20:53:06 +02:00
}
2019-03-02 15:17:41 +01:00
StageMenu . ExitButton = true ;
StageMenu . Display ( client , 0 ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public bool IsCorrectZone ( int index , char [ ] zoneIndexName , char [ ] zone_prefix )
{
ZoneNameBasedOnIndex ( index , zoneIndexName ) ;
if ( StrContains ( zoneIndexName , zone_prefix ) > - 1 )
{
return true ;
}
return false ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int Stage_menu ( Menu menu , MenuAction action , int client , int selection )
{
if ( action = = MenuAction_Select & & IsValidClient ( client ) )
{
selection + + ;
if ( ! g_iClientChecking [ client ] )
{
CheckTop ( client , selection , 1 ) ;
}
else
{
CheckStageSelf ( client , selection ) ;
}
}
else if ( action = = MenuAction_End )
{
delete ( menu ) ;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action cmd_timerCheckSelf ( int client , int args )
{
Checkself ( client ) ;
return Plugin_Handled ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void Checkself ( int client )
{
int l_iZoneCount = unloze_zoneCount ( ) ;
char l_cQuery [ g_dLength ] ;
char l_cSID [ g_dIndex ] ;
GetClientAuthId ( client , AuthId_Steam2 , l_cSID , sizeof ( l_cSID ) ) ;
2019-07-23 20:53:06 +02:00
if ( l_iZoneCount < 1 )
2019-03-02 15:17:41 +01:00
{
2019-07-23 20:53:06 +02:00
PrintToChat ( client , " No zones active on this map " ) ;
2019-03-02 15:17:41 +01:00
return ;
}
if ( l_iZoneCount < 2 )
{
Format ( l_cQuery , sizeof ( l_cQuery ) , " SELECT name, `%s` FROM `zetimer_table` WHERE steam_auth = '%s' " , g_cMapname , l_cSID ) ;
SQL_TQuery ( g_dDatabase , TqueryCheckSelf , l_cQuery , GetClientUserId ( client ) ) ;
}
else
{
CheckStagesOnMap ( client , 1 ) ;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckStageSelf ( int client , int selection )
{
char l_cQuery [ g_dLength ] ;
char l_cSID [ g_dIndex ] ;
GetClientAuthId ( client , AuthId_Steam2 , l_cSID , sizeof ( l_cSID ) ) ;
Format ( l_cQuery , sizeof ( l_cQuery ) , " SELECT name, `%sS%i` FROM `zetimer_table` WHERE steam_auth = '%s' " , g_cMapname , selection , l_cSID ) ;
SQL_TQuery ( g_dDatabase , TqueryCheckSelf , l_cQuery , GetClientUserId ( client ) ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void TqueryCheckSelf ( Handle db , Handle rs , const char [ ] error , any data )
{
int l_iMinutes ;
float l_fRecord ;
float l_iSeconds ;
char l_cMessageContent [ g_dLength ] ;
char [ ] l_cPlayerName = new char [ MAX_NAME_LENGTH ] ;
int client ;
if ( ( client = GetClientOfUserId ( data ) ) = = 0 )
return ;
if ( SQL_GetRowCount ( rs ) > 0 & & SQL_FetchRow ( rs ) )
{
SQL_FetchString ( rs , 0 , l_cPlayerName , MAX_NAME_LENGTH ) ;
l_fRecord = SQL_FetchFloat ( rs , 1 ) ;
if ( l_fRecord = = 0.000 )
{
CPrintToChat ( client , " You have no time yet! " ) ;
return ;
}
l_iMinutes = RoundToFloor ( l_fRecord ) ;
l_iSeconds = ( l_fRecord - l_iMinutes ) * 100 ;
Format ( l_cMessageContent , sizeof ( l_cMessageContent ) , " %i:%.1f - %s " , l_iMinutes , l_iSeconds , l_cPlayerName ) ;
CPrintToChat ( client , " Your best time: 0%s " , l_cMessageContent ) ;
}
else
CPrintToChat ( client , " You have no time yet! " ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
stock bool IsValidClient ( int client )
{
if ( client > 0 & & client < = MaxClients & & IsClientConnected ( client ) & & IsClientInGame ( client ) )
{
return true ;
}
return false ;
}