2019-03-02 15:17:41 +01:00
# pragma semicolon 1
# define DEBUG
# define PLUGIN_AUTHOR "jenz"
2022-08-09 01:39:41 +02:00
# define PLUGIN_VERSION "1.8"
2021-03-02 09:04:29 +01:00
# define g_dLength 400
2019-03-02 15:17:41 +01:00
# define g_dIndex 65
# include <sourcemod>
# include <colorvariables>
2019-08-04 12:59:39 +02:00
# include <clientprefs>
2019-03-02 15:17:41 +01:00
# include <unloze_zones>
# include <unloze_racetimer_specialmaps>
# include <unloze_racetimer_antizones>
# include <cstrike>
# include <sdktools>
2021-05-02 20:36:28 +02:00
# include <sdkhooks>
2022-08-09 01:39:41 +02:00
# include <connect>
2021-05-02 20:36:28 +02:00
# include <outputinfo>
2019-03-02 15:17:41 +01:00
# 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 ] ;
2021-02-25 23:44:03 +01:00
float g_fStartTime [ MAXPLAYERS + 1 ] ;
2021-07-29 15:17:49 +02:00
char g_csTime_record [ MAXPLAYERS + 1 ] [ 65 ] ;
2019-07-23 20:53:06 +02:00
float g_fClientVectors [ MAXPLAYERS + 1 ] [ 3 ] ;
2022-08-15 01:47:05 +02:00
float g_fClient_End_time [ MAXPLAYERS + 1 ] ;
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
int g_iClientChecking [ MAXPLAYERS + 1 ] ;
2023-03-27 23:17:19 +02:00
bool g_bClientsIgnoring [ MAXPLAYERS + 1 ] ;
2019-03-02 15:17:41 +01:00
bool g_bDisplaySpecial ;
2019-07-23 20:53:06 +02:00
bool g_bHumansAllowedTime [ MAXPLAYERS + 1 ] ;
2022-08-02 14:27:20 +02:00
bool g_bhumans_finished [ MAXPLAYERS + 1 ] ;
2019-07-24 00:43:06 +02:00
bool g_bHideTimer [ MAXPLAYERS + 1 ] ;
2021-02-25 23:44:03 +01:00
bool g_bEventBool = false ;
2022-08-15 01:47:05 +02:00
bool g_bClient_allowed_to_leave_again [ MAXPLAYERS + 1 ] ;
2019-08-04 12:59:39 +02:00
Handle g_hClientCookie = INVALID_HANDLE ;
2019-03-02 15:17:41 +01:00
Database g_dDatabase ;
2019-07-23 20:53:06 +02:00
Handle hText ;
2020-04-04 23:56:31 +02:00
int player_stage [ MAXPLAYERS + 1 ] ;
2022-08-10 13:17:09 +02:00
Handle g_hAlterTableTimer = null ;
2020-04-04 23:56:31 +02:00
2019-03-02 15:17:41 +01:00
public Plugin myinfo =
{
name = " UNLOZE_racetimer_css " ,
author = PLUGIN_AUTHOR ,
2022-08-09 01:39:41 +02:00
description = " tracks times on race maps on ze " ,
2019-03-02 15:17:41 +01:00
version = PLUGIN_VERSION ,
url = " www.unloze.com "
} ;
2021-02-25 23:44:03 +01:00
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart ( )
{
2022-08-09 01:39:41 +02:00
//cmds
RegConsoleCmd ( " sm_toptime " , cmd_timerCheckTop , " checking top 10 " ) ;
2023-03-27 23:17:19 +02:00
RegConsoleCmd ( " sm_ignoretimer " , cmd_timerIgnoreTime , " All racetimer will be ignored for you " ) ;
RegConsoleCmd ( " sm_ignoretime " , cmd_timerIgnoreTime , " All racetimer will be ignored for you " ) ;
2022-08-09 01:39:41 +02:00
RegConsoleCmd ( " sm_mytime " , cmd_timerCheckSelf , " checking your personal time " ) ;
RegConsoleCmd ( " sm_stages " , cmd_timerCheckStage , " Checking race stages " ) ;
RegConsoleCmd ( " sm_hidetimer " , cmd_hideTimerHUD , " Hides timer HUD " ) ;
RegAdminCmd ( " sm_cleantime " , Cmd_timeReset , ADMFLAG_GENERIC ) ;
//hooks
HookEvent ( " round_start " , Event_RoundStart , EventHookMode_PostNoCopy ) ;
HookEntityOutput ( " trigger_multiple " , " OnTrigger " , Trigger_Multiple ) ;
HookEntityOutput ( " trigger_multiple " , " OnStartTouch " , Trigger_Multiple ) ;
HookEntityOutput ( " trigger_teleport " , " OnTrigger " , trigger_teleport ) ;
HookEntityOutput ( " trigger_teleport " , " OnStartTouch " , trigger_teleport ) ;
2022-08-11 16:05:18 +02:00
//DB
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
}
2022-08-09 01:39:41 +02:00
//HUD
hText = CreateHudSynchronizer ( ) ;
2022-08-10 13:17:09 +02:00
//Just constantly reruns the alter table query to handle new zones, less lazy solution would just be adding a forward for when zones were renamed
g_hAlterTableTimer = CreateTimer ( 10.00 , Timer_alter_tables , _ , TIMER_REPEAT ) ;
2022-08-09 01:39:41 +02:00
//cookies
g_hClientCookie = RegClientCookie ( " hide_timer_cookie " , " Hides the timer HUD " , CookieAccess_Private ) ;
for ( int i = MaxClients ; i > 0 ; - - i )
{
if ( ! AreClientCookiesCached ( i ) )
continue ;
OnClientCookiesCached ( i ) ;
}
2022-08-09 15:54:34 +02:00
g_bDisplaySpecial = unloze_gBSpecialMapDisplay ( ) ;
2019-08-04 12:59:39 +02:00
}
2021-02-25 23:44:03 +01:00
2023-04-30 15:21:36 +02:00
public Action allow_leaving_again ( Handle hTimer , int Serial )
2022-08-15 01:47:05 +02:00
{
2023-04-30 15:21:36 +02:00
int client ;
if ( ( client = GetClientFromSerial ( Serial ) ) = = 0 )
{
return ;
}
2022-08-15 01:47:05 +02:00
if ( IsValidClient ( client ) )
{
g_bClient_allowed_to_leave_again [ client ] = true ;
}
}
2022-08-10 13:17:09 +02:00
public Action Timer_alter_tables ( Handle hTimer )
{
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
}
else
{
startTimer ( ) ;
}
}
2021-05-02 20:36:28 +02:00
public void trigger_teleport ( const char [ ] output , int entity_index , int client , float delay )
{
2022-08-09 01:39:41 +02:00
if ( IsValidEdict ( entity_index ) & & IsValidClient ( client ) & & g_bHumansAllowedTime [ client ] )
2021-05-02 20:36:28 +02:00
{
2022-08-09 01:39:41 +02:00
//if its surf maps there most likely are needed teleports
2021-05-02 20:36:28 +02:00
if ( StrContains ( g_cMapname , " surf " , false ) = = - 1 )
{
2022-08-15 01:47:05 +02:00
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
resetClientVectors ( client ) ;
g_bClient_allowed_to_leave_again [ client ] = false ;
PrintToChat ( client , " Disabled timer due to potential teleport abuse, type 1. " ) ;
2023-04-30 15:21:36 +02:00
CreateTimer ( 1.0 , allow_leaving_again , GetClientSerial ( client ) ) ;
2021-05-02 20:36:28 +02:00
}
}
}
public void Trigger_Multiple ( const char [ ] output , int entity_index , int client , float delay )
{
2022-08-02 14:27:20 +02:00
if ( IsValidEdict ( entity_index ) & & origin_command_check ( entity_index ) & & IsValidClient ( client ) & & g_bHumansAllowedTime [ client ] )
{
2022-08-09 01:39:41 +02:00
if ( StrContains ( g_cMapname , " surf " , false ) = = - 1 )
{
g_bHumansAllowedTime [ client ] = false ;
2022-08-15 01:47:05 +02:00
g_bhumans_finished [ client ] = false ;
2022-08-09 01:39:41 +02:00
resetClientVectors ( client ) ;
2022-08-15 01:47:05 +02:00
g_bClient_allowed_to_leave_again [ client ] = false ;
PrintToChat ( client , " Disabled timer due to potential teleport abuse, type 1. " ) ;
2023-04-30 15:21:36 +02:00
CreateTimer ( 1.0 , allow_leaving_again , GetClientSerial ( client ) ) ;
2022-08-09 01:39:41 +02:00
}
2022-08-02 14:27:20 +02:00
}
2021-05-02 20:36:28 +02:00
}
public bool origin_command_check ( int entity_index )
{
int count_trigger = GetOutputCount ( entity_index , " m_OnTrigger " ) ;
int count_starttouch = GetOutputCount ( entity_index , " m_OnStartTouch " ) ;
for ( int i = 0 ; i < count_trigger ; i + + )
{
2022-08-09 01:39:41 +02:00
char buffer [ g_dLength ] ;
GetOutputParameter ( entity_index , " m_OnTrigger " , i , buffer , sizeof ( buffer ) ) ;
if ( StrContains ( buffer , " origin " , true ) ! = - 1 )
return true ;
2021-05-02 20:36:28 +02:00
}
2022-08-09 01:39:41 +02:00
for ( int i = 0 ; i < count_starttouch ; i + + )
2021-05-02 20:36:28 +02:00
{
2022-08-09 01:39:41 +02:00
char buffer [ g_dLength ] ;
GetOutputParameter ( entity_index , " m_OnStartTouch " , i , buffer , sizeof ( buffer ) ) ;
if ( StrContains ( buffer , " origin " , true ) ! = - 1 )
return true ;
2021-05-02 20:36:28 +02:00
}
return false ;
}
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2021-01-26 19:49:43 +01:00
public void SQL_OnDatabaseConnect ( Database db , const char [ ] error , any data )
2019-03-02 15:17:41 +01:00
{
2022-08-09 01:39:41 +02:00
if ( ! db | | strlen ( error ) )
{
LogError ( " Database error: %s " , error ) ;
return ;
}
g_dDatabase = db ;
//create tables
char sQuery [ g_dLength ] ;
Format ( sQuery , sizeof ( sQuery ) , " CREATE TABLE IF NOT EXISTS `zetimer_table_new` (`steam_auth` VARCHAR(254) NOT NULL, `name` VARCHAR(254) NOT NULL, PRIMARY KEY (`steam_auth`)) " ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_OnConnectFinished , sQuery , _ , DBPrio_Normal ) ;
2021-02-25 23:44:03 +01:00
}
2021-01-26 19:49:43 +01:00
2021-02-25 23:44:03 +01:00
public void SQL_OnConnectFinished ( Database db , DBResultSet results , const char [ ] error , any data )
{
2022-08-09 01:39:41 +02:00
if ( ! db | | strlen ( error ) )
{
2023-04-30 12:14:28 +02:00
delete results ;
2022-08-09 01:39:41 +02:00
LogError ( " Database error: %s " , error ) ;
2021-03-02 12:50:08 +01:00
return ;
2022-08-09 01:39:41 +02:00
}
static Handle hHostName ;
if ( ( hHostName = FindConVar ( " hostname " ) ) = = INVALID_HANDLE )
2023-04-30 12:14:28 +02:00
{
delete results ;
2022-08-09 01:39:41 +02:00
return ;
2023-04-30 12:14:28 +02:00
}
2022-08-09 01:39:41 +02:00
char line [ g_dLength ] ;
GetConVarString ( hHostName , line , sizeof ( line ) ) ;
if ( StrContains ( line , " EVENT " , false ) > - 1 )
g_bEventBool = true ;
else
g_bEventBool = false ;
g_bDisplaySpecial = unloze_gBSpecialMapDisplay ( ) ;
GetCurrentMap ( g_cMapname , sizeof ( g_cMapname ) ) ;
startTimer ( ) ;
2021-01-26 19:49:43 +01:00
2022-08-09 01:39:41 +02:00
for ( int i = 1 ; i < = MaxClients ; i + + )
if ( IsValidClient ( i ) )
OnClientPostAdminCheck ( i ) ;
2022-08-11 16:05:18 +02:00
AddBinarySearchIndex ( ) ;
2023-04-30 12:14:28 +02:00
delete results ;
2021-01-26 19:49:43 +01:00
}
2021-02-25 23:44:03 +01:00
public void MYSQLCheckMapEntry ( )
2021-01-26 19:49:43 +01:00
{
2022-08-10 13:17:09 +02:00
int l_iRaceCount ;
int l_iZoneCount = unloze_zoneCount ( ) ;
char sQuery [ g_dLength ] ;
if ( l_iZoneCount = = 1 )
{
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table_new` ADD COLUMN IF NOT EXISTS `%s` REAL DEFAULT 0.000 NOT NULL " , g_cMapname ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2022-08-10 13:17:09 +02:00
}
else
{
for ( int iterator = 0 ; iterator < = l_iZoneCount ; iterator + + )
{
2022-08-15 01:47:05 +02:00
char zoneIndexName [ 512 ] ;
ZoneNameBasedOnIndex ( iterator , zoneIndexName ) ;
if ( StrContains ( zoneIndexName , " ZONE_PREFIX_RACE " ) > - 1 )
2022-08-10 13:17:09 +02:00
{
l_iRaceCount + + ;
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table_new` ADD COLUMN IF NOT EXISTS `%sS%i` REAL DEFAULT 0.000 NOT NULL " , g_cMapname , l_iRaceCount ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2022-08-10 13:17:09 +02:00
}
}
}
2021-01-26 19:49:43 +01:00
}
2021-02-28 23:47:41 +01:00
public void SQL_FinishedQuery ( Database db , DBResultSet results , const char [ ] error , DataPack data )
2021-01-26 19:49:43 +01:00
{
2023-04-30 12:14:28 +02:00
delete results ;
if ( ! db | | strlen ( error ) )
{
char sQuery [ g_dLength ] ;
ResetPack ( data ) ;
data . ReadString ( sQuery , sizeof ( sQuery ) ) ;
LogError ( " Query error 3: %s " , error ) ;
LogError ( " actual query: %s " , sQuery ) ;
}
delete data ;
2021-01-26 19:49:43 +01:00
}
2022-08-11 16:05:18 +02:00
//a mysql table can max have 64 keys attached to it without recompiling. Therefore dropping and attaching binary tree index on the given map start, map end,
//PluginStart Database connection and PluginEnd.
//Adding and removing indexes should be pretty cheap so creating/removing them for only the specific map should be ok
//also check that racezones actually exist before making a binary tree index
//also handles if the column ends with just mapname or with mapnameS1, mapnameS2 etc etc
//its only relevant for sourcemod scripting part, the java backend making rest endpoints uses a cache and does select * statements so it does not need indexing
public void AddBinarySearchIndex ( )
{
int race_zone_count = GetTotalRaceZones ( ) ;
int l_iZoneCount = unloze_zoneCount ( ) ;
char sQuery [ g_dLength ] ;
GetCurrentMap ( g_cMapname , sizeof ( g_cMapname ) ) ;
//if admins dont make dumb random zones without any meaning it works fine
if ( race_zone_count = = 1 & & l_iZoneCount = = 1 )
{
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table_new` add INDEX if not exists `%s` (`%s`) " , g_cMapname , g_cMapname ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2022-08-11 16:05:18 +02:00
}
else
{
for ( int i = 1 ; i < = race_zone_count ; i + + )
{
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table_new` add INDEX if not exists `%sS%i` (`%sS%i`) " , g_cMapname , i , g_cMapname , i ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2022-08-11 16:05:18 +02:00
}
}
}
//if ze1 and ze2 both play the same map and one leaves the map then the other will not have index anymore, but otherwise its fine.
public void RemoveBinarySearchIndex ( )
{
char sQuery [ g_dLength ] ;
int race_zone_count = GetTotalRaceZones ( ) ;
int l_iZoneCount = unloze_zoneCount ( ) ;
GetCurrentMap ( g_cMapname , sizeof ( g_cMapname ) ) ;
if ( race_zone_count = = 1 & & l_iZoneCount = = 1 )
{
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table_new` drop INDEX if exists `%s` " , g_cMapname ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2022-08-11 16:05:18 +02:00
}
else
{
for ( int i = 1 ; i < = race_zone_count ; i + + )
{
Format ( sQuery , sizeof ( sQuery ) , " ALTER TABLE `zetimer_table_new` drop INDEX if exists `%sS%i` " , g_cMapname , i ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2022-08-11 16:05:18 +02:00
}
}
}
public void OnMapEnd ( )
{
if ( ! g_dDatabase )
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
else
RemoveBinarySearchIndex ( ) ;
}
2021-01-26 19:49:43 +01:00
public void OnMapStart ( )
{
2022-08-09 15:54:34 +02:00
if ( ! g_dDatabase )
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
else
{
2022-08-11 16:05:18 +02:00
AddBinarySearchIndex ( ) ;
2022-08-09 15:54:34 +02:00
static Handle hHostName ;
if ( ( hHostName = FindConVar ( " hostname " ) ) = = INVALID_HANDLE )
return ;
char line [ g_dLength ] ;
GetConVarString ( hHostName , line , sizeof ( line ) ) ;
if ( StrContains ( line , " EVENT " , false ) > - 1 )
g_bEventBool = true ;
else
g_bEventBool = false ;
g_bDisplaySpecial = unloze_gBSpecialMapDisplay ( ) ;
GetCurrentMap ( g_cMapname , sizeof ( g_cMapname ) ) ;
}
Format ( g_cSpecialMapStart , sizeof ( g_cSpecialMapStart ) , " " ) ;
Format ( g_cSpecialMapEnd , sizeof ( g_cSpecialMapEnd ) , " " ) ;
2021-03-08 21:47:50 +01:00
}
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-07-23 20:53:06 +02:00
public void OnPluginEnd ( )
{
2022-08-10 13:17:09 +02:00
CloseHandle ( hText ) ;
if ( g_hAlterTableTimer ! = null )
delete g_hAlterTableTimer ;
2022-08-11 16:05:18 +02:00
RemoveBinarySearchIndex ( ) ;
2019-07-23 20:53:06 +02:00
}
//----------------------------------------------------------------------------------------------------
// 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 void Event_RoundStart ( Handle event , const char [ ] name , bool dontBroadcast )
{
2022-08-09 15:54:34 +02:00
Format ( g_cSpecialMapStart , sizeof ( g_cSpecialMapStart ) , " " ) ;
Format ( g_cSpecialMapEnd , sizeof ( g_cSpecialMapEnd ) , " " ) ;
2022-08-09 01:39:41 +02:00
int race_zone_count = GetTotalRaceZones ( ) ;
2022-08-17 21:07:31 +02:00
int l_iZoneCount = unloze_zoneCount ( ) ;
2022-08-09 01:39:41 +02:00
if ( ! race_zone_count )
return ;
for ( int i = 1 ; i < = MaxClients ; i + + )
if ( IsValidClient ( i ) & & ! IsFakeClient ( i ) )
{
2022-08-02 14:27:20 +02:00
g_bhumans_finished [ i ] = false ;
2022-08-15 01:47:05 +02:00
g_fClient_End_time [ i ] = 0.0 ;
2022-08-02 14:27:20 +02:00
resetClientVectors ( i ) ;
2022-08-10 00:55:03 +02:00
char first_zone [ 512 ] ;
ZoneNameBasedOnIndex ( 0 , first_zone ) ;
2022-08-15 01:47:05 +02:00
g_bClient_allowed_to_leave_again [ i ] = true ;
2022-08-17 21:07:31 +02:00
g_bHumansAllowedTime [ i ] = false ;
if ( l_iZoneCount = = 1 & & race_zone_count = = 1 )
2022-08-02 14:27:20 +02:00
{
g_bHumansAllowedTime [ i ] = true ;
2023-04-29 13:41:32 +02:00
PrintToChat ( i , " Started timer: There is only a finish zone " ) ;
2022-08-02 14:27:20 +02:00
g_fStartTime [ i ] = GetEngineTime ( ) ;
2022-08-15 01:47:05 +02:00
mysql_get_player_time ( i , 0 ) ;
2022-08-02 14:27:20 +02:00
}
}
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientPostAdminCheck ( int client )
{
2023-03-27 23:17:19 +02:00
resetClient ( client ) ;
insertPlayerMYSQL ( client ) ;
client_ignoring_racetimer ( client ) ;
}
public void client_ignoring_racetimer ( int client )
{
char query [ g_dLength ] ;
char steam_auth [ g_dIndex ] ;
GetClientAuthId ( client , AuthId_Steam2 , steam_auth , sizeof ( steam_auth ) ) ;
Format ( query , sizeof ( query ) , " SELECT is_ignoring FROM `zetimer_table_new_ignoring` where steam_auth = '%s' " , steam_auth ) ;
2023-04-30 12:14:28 +02:00
g_dDatabase . Query ( SQL_OnQueryCompleted_ignoring , query , GetClientSerial ( client ) ) ;
2023-03-27 23:17:19 +02:00
}
2023-04-30 12:14:28 +02:00
public void SQL_OnQueryCompleted_ignoring ( Database db , DBResultSet results , const char [ ] error , int Serial )
2023-03-27 23:17:19 +02:00
{
if ( ! db )
{
2023-04-30 12:14:28 +02:00
delete results ;
return ;
}
int client ;
if ( ( client = GetClientFromSerial ( Serial ) ) = = 0 )
{
delete results ;
2023-03-27 23:17:19 +02:00
return ;
}
if ( ! IsValidClient ( client ) )
2023-04-30 12:14:28 +02:00
{
delete results ;
2023-03-27 23:17:19 +02:00
return ;
2023-04-30 12:14:28 +02:00
}
2023-03-27 23:17:19 +02:00
int val = 0 ;
if ( results . RowCount & & results . FetchRow ( ) )
val = results . FetchInt ( 0 ) ;
g_bClientsIgnoring [ client ] = false ;
if ( val = = 1 )
{
g_bClientsIgnoring [ client ] = true ;
}
2023-04-30 12:14:28 +02:00
delete results ;
2019-08-04 12:59:39 +02:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientCookiesCached ( int client )
{
char sValue [ 8 ] ;
GetClientCookie ( client , g_hClientCookie , sValue , sizeof ( sValue ) ) ;
g_bHideTimer [ client ] = ( sValue [ 0 ] ! = '\0' & & ! ! StringToInt ( sValue ) ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientDisconnect ( int client )
{
resetClient ( client ) ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void resetClient ( int client )
{
2022-08-02 14:27:20 +02:00
if ( 0 < client < = MaxClients )
{
g_iClientChecking [ client ] = 0 ;
2023-03-27 23:17:19 +02:00
g_bClientsIgnoring [ client ] = false ;
2022-08-02 14:27:20 +02:00
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
2022-08-15 01:47:05 +02:00
g_fClient_End_time [ client ] = 0.0 ;
g_bClient_allowed_to_leave_again [ client ] = false ;
2022-08-02 14:27:20 +02:00
resetClientVectors ( client ) ;
2022-08-09 01:39:41 +02:00
g_fStartTime [ client ] = 0.0 ;
2022-08-02 14:27:20 +02:00
player_stage [ client ] = 0 ;
Format ( g_csTime_record [ client ] , sizeof ( g_csTime_record [ ] ) , " 0.000 " ) ;
}
2019-07-23 20:53:06 +02:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2021-02-25 23:44:03 +01:00
public void OnPlayerRunCmdPost ( int client , int buttons , int impulse , const float vel [ 3 ] , const float angles [ 3 ] , int weapon , int subtype , int cmdnum , int tickcount , int seed , const int mouse [ 2 ] )
2019-07-23 20:53:06 +02:00
{
2022-08-09 01:39:41 +02:00
if ( ! IsValidClient ( client ) )
return ;
if ( ! g_bHumansAllowedTime [ client ] )
return ;
2022-08-02 14:27:20 +02:00
//checks if event is going on
2022-08-09 01:39:41 +02:00
if ( g_bEventBool )
{
g_bHumansAllowedTime [ client ] = false ;
2023-04-29 13:26:37 +02:00
PrintToChat ( client , " Disabling timer due to map being marked as event map. " ) ;
2022-08-09 01:39:41 +02:00
return ;
}
2022-08-15 01:47:05 +02:00
if ( ! IsPlayerAlive ( client ) )
2022-08-02 14:27:20 +02:00
{
2022-08-15 01:47:05 +02:00
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to dying. " ) ;
return ;
}
if ( GetClientTeam ( client ) = = CS_TEAM_CT )
{
float clientVectors [ 3 ] ;
GetClientAbsOrigin ( client , clientVectors ) ;
if ( checkClientOrigin ( g_fClientVectors [ client ] , clientVectors , client ) )
{
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
resetClientVectors ( client ) ;
g_bClient_allowed_to_leave_again [ client ] = false ;
PrintToChat ( client , " Disabled timer due to potential teleport abuse, type 2. " ) ;
2023-04-30 15:21:36 +02:00
CreateTimer ( 1.0 , allow_leaving_again , GetClientSerial ( client ) ) ;
2022-08-15 01:47:05 +02:00
return ;
}
2022-08-02 14:27:20 +02:00
int frameCap = 11 ;
if ( g_bhumans_finished [ client ] )
g_iClientFrames [ client ] = 11 ;
if ( g_iClientFrames [ client ] > = frameCap )
{
g_iClientFrames [ client ] = 0 ;
if ( g_bhumans_finished [ client ] )
{
2022-08-09 01:39:41 +02:00
resetClientVectors ( client ) ;
2022-08-02 14:27:20 +02:00
g_bhumans_finished [ client ] = false ;
g_bHumansAllowedTime [ client ] = false ;
FinishedStageRaceZone ( client ) ;
return ;
}
int speedCheckerCap = 10 ;
if ( g_iClientSpeedInterval [ client ] > speedCheckerCap )
{
g_iClientSpeedInterval [ client ] = 0 ;
bool bNoclip = ( GetEntityMoveType ( client ) = = MOVETYPE_NOCLIP ) ;
if ( bNoclip )
{
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to Noclip " ) ;
return ;
}
float speed = GetEntPropFloat ( client , Prop_Data , " m_flLaggedMovementValue " ) ;
if ( speed > 1.0 )
{
if ( StrContains ( g_cMapname , " surf " , false ) = = - 1 )
{
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to modified run speed " ) ;
return ;
}
}
float client_gravity = GetEntityGravity ( client ) ;
ConVar gravity = FindConVar ( " sv_gravity " ) ;
float gravityFloat = gravity . FloatValue ;
int minimalPermitedGravity = 610 ;
//PrintToChat(client, "client_gravity: %f\ngravityFloat: %f", client_gravity, gravityFloat);
if ( ( ( client_gravity > 1.3 | | client_gravity < 0.6000 ) & & client_gravity ! = 0.000000 ) | | gravityFloat < minimalPermitedGravity )
{
//PrintToChat(client, "client_gravity: %f\ngravityFloat: %f", client_gravity, gravityFloat);
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to modified gravity " ) ;
return ;
}
}
g_fClientVectors [ client ] = clientVectors ;
if ( hText ! = INVALID_HANDLE & & ! g_bHideTimer [ client ] )
{
SetHudTextParams ( 0.35 , 0.85 , 0.1 , 125 , 255 , 255 , 85 ) ;
float total_time = client_current_race_time ( client ) ;
2022-08-09 01:39:41 +02:00
if ( total_time ! = - 1.0 )
ShowSyncHudText ( client , hText , " %N Time: %06.3f \n Record: %s \n Map: %s \n Course: %i " , client , total_time , g_csTime_record [ client ] , g_cMapname , player_stage [ client ] ) ;
2022-08-02 14:27:20 +02:00
}
g_iClientSpeedInterval [ client ] + + ;
}
g_iClientFrames [ client ] + + ;
}
2022-08-15 01:47:05 +02:00
else
{
//is zm
g_bHumansAllowedTime [ client ] = false ;
g_bhumans_finished [ client ] = false ;
//called if teleported to some place far away or teleported from inside start zone to end zone
resetClientVectors ( client ) ;
PrintToChat ( client , " Disabled timer due to ZM infection. " ) ;
return ;
}
2022-08-09 01:39:41 +02:00
return ;
2021-02-25 23:44:03 +01:00
}
public float client_current_race_time ( int i_client )
{
2022-08-09 01:39:41 +02:00
if ( g_fStartTime [ i_client ] = = 0.0 )
return - 1.0 ;
return GetEngineTime ( ) - g_fStartTime [ i_client ] ;
2019-07-23 20:53:06 +02:00
}
2021-02-25 23:44:03 +01:00
2019-07-23 20:53:06 +02:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void resetClientVectors ( int client )
{
2021-04-27 19:50:16 +02:00
g_fClientVectors [ client ] [ 0 ] = 0.000000 ;
g_fClientVectors [ client ] [ 1 ] = 0.000000 ;
g_fClientVectors [ client ] [ 2 ] = 0.000000 ;
2019-07-23 20:53:06 +02:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-07-25 01:31:10 +02:00
public bool checkClientOrigin ( float oldVals [ 3 ] , float newVals [ 3 ] , int client )
2019-07-23 20:53:06 +02:00
{
float zero = 0.000000 ;
if ( ( oldVals [ 0 ] = = zero & & oldVals [ 1 ] = = zero & & oldVals [ 2 ] = = zero ) | | ( newVals [ 0 ] = = zero & & newVals [ 1 ] = = zero & & newVals [ 2 ] = = zero ) )
{
return false ;
}
2021-05-02 20:36:28 +02:00
float teleport_range = 1090450.0 ;
2021-01-26 19:49:43 +01:00
int velocityCap = 625 ;
2019-07-23 20:53:06 +02:00
float distance = GetVectorDistance ( oldVals , newVals , true ) ;
bool bInAir = ( GetEntPropEnt ( client , Prop_Send , " m_hGroundEntity " ) = = - 1 ) ;
if ( distance > teleport_range )
2019-08-19 15:32:35 +02:00
{
2019-07-23 20:53:06 +02:00
if ( StrContains ( g_cMapname , " surf " , false ) ! = - 1 )
return false ;
2019-07-25 01:31:10 +02:00
float fVelocity [ 3 ] ;
GetEntPropVector ( client , Prop_Data , " m_vecVelocity " , fVelocity ) ;
float currentspeed = SquareRoot ( Pow ( fVelocity [ 0 ] , 2.0 ) + Pow ( fVelocity [ 1 ] , 2.0 ) ) ;
//PrintToChat(client, "currentspeed: %f", currentspeed);
if ( bInAir & & currentspeed > velocityCap )
2019-07-23 20:53:06 +02:00
return false ;
return true ;
}
return false ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void unloze_zoneEntry ( int client , char [ ] zone )
{
2023-03-27 23:17:19 +02:00
if ( g_bClientsIgnoring [ client ] )
{
return ;
}
2022-08-02 14:27:20 +02:00
int zoneIndex = RetrieveZoneIndex ( zone ) ;
2022-08-09 01:39:41 +02:00
int race_zone_count = GetTotalRaceZones ( ) ;
2022-08-09 15:54:34 +02:00
if ( ! ( StrEqual ( zone , g_cSpecialMapEnd ) ) & & ! race_zone_count )
2022-08-09 01:39:41 +02:00
return ;
2022-08-02 14:27:20 +02:00
int l_iZoneCount = unloze_zoneCount ( ) ;
2022-08-09 15:54:34 +02:00
if ( GetClientTeam ( client ) = = CS_TEAM_CT & & ( g_bHumansAllowedTime [ client ] | | StrEqual ( zone , g_cSpecialMapEnd ) ) )
2022-08-02 14:27:20 +02:00
{
if ( ( StrContains ( zone , " ZONE_PREFIX_RACE " ) > - 1 ) | | StrEqual ( zone , g_cSpecialMapEnd ) )
{
if ( l_iZoneCount < 2 )
player_stage [ client ] = 0 ;
if ( player_stage [ client ] = = ( zoneIndex / 2 ) | | l_iZoneCount < 2 )
{
g_bhumans_finished [ client ] = true ;
2022-08-15 01:47:05 +02:00
g_fClient_End_time [ client ] = client_current_race_time ( client ) ;
2022-08-02 14:27:20 +02:00
}
}
}
2019-03-02 15:17:41 +01:00
}
2022-08-09 01:39:41 +02:00
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
2023-03-27 23:17:19 +02:00
if ( g_bClientsIgnoring [ client ] )
{
return ;
}
2022-08-09 01:39:41 +02:00
int race_zone_count = GetTotalRaceZones ( ) ;
2022-08-15 01:47:05 +02:00
if ( ! ( StrEqual ( zone , g_cSpecialMapStart ) ) & & ! race_zone_count )
2022-08-09 01:39:41 +02:00
return ;
if ( GetClientTeam ( client ) = = CS_TEAM_CT )
2022-08-02 14:27:20 +02:00
{
if ( ( StrContains ( zone , " ZONE_PREFIX_START " ) > - 1 ) | | StrEqual ( zone , g_cSpecialMapStart ) )
{
2022-08-09 01:39:41 +02:00
char sAuthID [ 32 ] ;
GetClientAuthId ( client , AuthId_Steam2 , sAuthID , sizeof ( sAuthID ) , false ) ;
if ( ! SteamClientAuthenticated ( sAuthID ) )
{
PrintToChat ( client , " Not starting timer due to being listed as nosteamer " ) ;
2022-08-02 14:27:20 +02:00
return ;
2022-08-09 01:39:41 +02:00
}
2022-08-15 01:47:05 +02:00
if ( ! g_bClient_allowed_to_leave_again [ client ] )
{
2023-04-30 12:14:28 +02:00
PrintToChat ( client , " Did not start timer due to teleport cooldown. " ) ;
2022-08-15 01:47:05 +02:00
return ;
}
2022-08-09 01:39:41 +02:00
2022-08-02 14:27:20 +02:00
g_fStartTime [ client ] = GetEngineTime ( ) ;
float notRounded = float ( RetrieveZoneIndex ( zone ) ) ;
player_stage [ client ] = RoundToCeil ( notRounded / 2 ) ;
CPrintToChat ( client , " Timer started for Course: %i " , player_stage [ client ] ) ;
2022-08-15 01:47:05 +02:00
g_bHumansAllowedTime [ client ] = true ;
mysql_get_player_time ( client , player_stage [ client ] ) ;
2022-08-02 14:27:20 +02:00
}
}
2019-03-02 15:17:41 +01:00
}
2021-02-25 23:44:03 +01:00
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckIfSpecialRoundZones ( char [ ] resultstart , char [ ] resultend )
{
2022-08-09 15:54:34 +02:00
Format ( g_cSpecialMapStart , sizeof ( g_cSpecialMapStart ) , resultstart ) ;
Format ( g_cSpecialMapEnd , sizeof ( g_cSpecialMapEnd ) , resultend ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckifAntiZones ( int client , bool reset )
{
2023-04-30 15:21:36 +02:00
if ( reset & & g_bHumansAllowedTime [ client ] )
2023-04-29 13:41:32 +02:00
{
g_bHumansAllowedTime [ client ] = false ;
PrintToChat ( client , " Disabled Timer due to using illegal shortcut " ) ;
}
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 ;
2020-04-15 01:00:12 +02:00
if ( iterator = = - 1 )
return 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 )
{
2022-08-09 01:39:41 +02:00
char sSID [ g_dIndex ] ;
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 ] ;
2021-02-28 23:47:41 +01:00
2022-08-09 01:39:41 +02:00
g_dDatabase . Escape ( sName , sEscapedName , size2 + 1 ) ;
2021-02-28 23:47:41 +01:00
2022-08-09 01:39:41 +02:00
if ( StrEqual ( sSID , " STEAM_ID_STOP_IGNORING_RETVALS " ) | | StrEqual ( sSID , " STEAM_ID_PENDING " ) )
{
PrintToChat ( client , " Your steam ID is not working, not updating timer " ) ;
return ;
}
2021-02-28 23:47:41 +01:00
2022-08-09 01:39:41 +02:00
int l_iZoneCount = unloze_zoneCount ( ) ;
2022-08-15 01:47:05 +02:00
float client_time = g_fClient_End_time [ client ] ;
2022-08-09 01:39:41 +02:00
if ( client_time = = - 1.0 )
{
//if client disconnected we dont want to cary timer over to other client
return ;
}
if ( l_iZoneCount > 1 )
CPrintToChat ( client , " {green}[UNLOZE] Stage: %i " , player_stage [ client ] ) ;
2023-04-30 12:14:28 +02:00
CPrintToChat ( client , " {green}[UNLOZE] Time: %06.3f " , client_time ) ;
2022-08-09 01:39:41 +02:00
int stage = player_stage [ client ] ;
char sQuery [ g_dLength ] ;
if ( StrEqual ( g_csTime_record [ client ] , " 0.000 " ) )
{
2023-04-30 12:14:28 +02:00
CPrintToChat ( client , " {green}[UNLOZE] Your record: None yet \n Command: !toptime !mytime !stages " ) ;
2022-08-09 01:39:41 +02:00
}
else
{
2023-04-30 12:14:28 +02:00
CPrintToChat ( client , " {green}[UNLOZE] Your record: %s \n Command: !toptime !mytime !stages " , g_csTime_record [ client ] ) ;
2022-08-09 01:39:41 +02:00
}
if ( l_iZoneCount < 2 )
Format ( sQuery , sizeof ( sQuery ) , " UPDATE `zetimer_table_new` SET `%s` = '%06.3f', name = '%s' WHERE steam_auth = '%s' " , g_cMapname , client_time , sEscapedName , sSID ) ;
else
Format ( sQuery , sizeof ( sQuery ) , " UPDATE `zetimer_table_new` SET `%sS%i` = '%06.3f', name = '%s' WHERE steam_auth = '%s' " , g_cMapname , stage , client_time , sEscapedName , sSID ) ;
int generic_length = 32 ;
char [ ] [ ] sPart = new char [ 2 ] [ generic_length ] ;
float old_client_time = 0.0 ;
if ( StrContains ( g_csTime_record [ client ] , " : " ) ! = - 1 )
{
ExplodeString ( g_csTime_record [ client ] , " : " , sPart , 2 , generic_length ) ;
old_client_time = ( StringToFloat ( sPart [ 0 ] ) * 60 ) + StringToFloat ( sPart [ 1 ] ) ;
}
else
{
old_client_time = StringToFloat ( g_csTime_record [ client ] ) ;
}
if ( client_time > = old_client_time & & old_client_time > 0.0 )
{
return ;
}
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2020-04-04 23:56:31 +02:00
public void mysql_get_player_time ( int client , int stage )
{
2022-08-12 01:03:20 +02:00
char query [ g_dLength ] ;
char steam_auth [ g_dIndex ] ;
GetClientAuthId ( client , AuthId_Steam2 , steam_auth , sizeof ( steam_auth ) ) ;
if ( ! stage )
{
Format ( query , sizeof ( query ) , " SELECT `%s` FROM `zetimer_table_new` where steam_auth = '%s' " , g_cMapname , steam_auth ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteCell ( GetClientSerial ( client ) ) ;
g_dDatabase . Query ( SQL_OnQueryCompleted_retry , query , hDataPack ) ;
}
else
{
Format ( query , sizeof ( query ) , " SELECT `%sS%i` FROM `zetimer_table_new` where steam_auth = '%s' " , g_cMapname , stage , steam_auth ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteCell ( GetClientSerial ( client ) ) ;
2021-02-28 23:47:41 +01:00
hDataPack . WriteString ( query ) ;
2022-08-12 01:03:20 +02:00
g_dDatabase . Query ( SQL_OnQueryCompleted , query , hDataPack ) ;
}
}
//we only enter here when stage is 0. that might however be incorrect as it instead might need to be S1. Simply a band aid instead of fixing actual problem.
public void SQL_OnQueryCompleted_retry ( Database db , DBResultSet results , const char [ ] error , DataPack data )
{
ResetPack ( data ) ;
int client_serial = data . ReadCell ( ) ;
delete data ;
if ( ! db )
{
2023-04-30 12:14:28 +02:00
delete results ;
2022-08-12 01:03:20 +02:00
return ;
}
int client ;
if ( ( client = GetClientFromSerial ( client_serial ) ) = = 0 )
2023-04-30 12:14:28 +02:00
{
delete results ;
2022-08-12 01:03:20 +02:00
return ;
2023-04-30 12:14:28 +02:00
}
2022-08-12 01:03:20 +02:00
if ( strlen ( error ) )
{
2023-04-30 12:14:28 +02:00
delete results ;
2022-08-12 01:03:20 +02:00
mysql_get_player_time ( client , 1 ) ;
return ;
}
if ( results . RowCount & & results . FetchRow ( ) )
results . FetchString ( 0 , g_csTime_record [ client ] , sizeof ( g_csTime_record [ ] ) ) ;
2023-04-30 12:14:28 +02:00
delete results ;
2020-04-04 23:56:31 +02:00
}
2021-03-02 12:50:08 +01:00
public void SQL_OnQueryCompleted ( Database db , DBResultSet results , const char [ ] error , DataPack data )
{
2022-08-09 01:39:41 +02:00
ResetPack ( data ) ;
int client_serial = data . ReadCell ( ) ;
if ( ! db | | strlen ( error ) )
{
char sQuery [ g_dLength ] ;
data . ReadString ( sQuery , sizeof ( sQuery ) ) ;
LogError ( " Query error 1: %s " , error ) ;
LogError ( " actual query: %s " , sQuery ) ;
delete data ;
2023-04-30 12:14:28 +02:00
delete results ;
2022-08-09 01:39:41 +02:00
return ;
}
delete data ;
int client ;
if ( ( client = GetClientFromSerial ( client_serial ) ) = = 0 )
2023-04-30 12:14:28 +02:00
{
delete results ;
2022-08-09 01:39:41 +02:00
return ;
2023-04-30 12:14:28 +02:00
}
2022-08-09 01:39:41 +02:00
if ( results . RowCount & & results . FetchRow ( ) )
results . FetchString ( 0 , g_csTime_record [ client ] , sizeof ( g_csTime_record [ ] ) ) ;
2023-04-30 12:14:28 +02:00
delete results ;
2021-03-02 12:50:08 +01:00
}
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:
//----------------------------------------------------------------------------------------------------
2021-02-28 23:47:41 +01:00
public void insertPlayerMYSQL ( int client )
2019-03-02 15:17:41 +01:00
{
2022-08-09 01:39:41 +02:00
if ( ! IsValidClient ( client ) )
return ;
char sSID [ g_dIndex ] ;
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 ] ;
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
return ;
}
g_dDatabase . Escape ( sName , sEscapedName , size2 + 1 ) ;
if ( StrEqual ( sSID , " STEAM_ID_STOP_IGNORING_RETVALS " ) | | StrEqual ( sSID , " STEAM_ID_PENDING " ) )
{
PrintToChat ( client , " Your steam ID is not working, not updating timer " ) ;
return ;
}
Format ( sQuery , sizeof ( sQuery ) , " INSERT INTO `zetimer_table_new` (`steam_auth`, `name`) VALUES ('%s', '%s') ON DUPLICATE KEY UPDATE `name` = '%s' " , sSID , sEscapedName , sEscapedName ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
2023-02-19 15:41:54 +01:00
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
2019-03-02 15:17:41 +01:00
}
2021-01-26 19:49:43 +01:00
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2023-03-27 23:17:19 +02:00
public Action cmd_timerIgnoreTime ( int client , int args )
{
insert_client_ignoring_racetimer ( client ) ;
return Plugin_Handled ;
}
public void insert_client_ignoring_racetimer ( int client )
{
if ( ! IsValidClient ( client ) )
return ;
if ( g_bClientsIgnoring [ client ] )
{
g_bClientsIgnoring [ client ] = false ;
g_bHideTimer [ client ] = false ;
SetClientCookie ( client , g_hClientCookie , " 0 " ) ;
PrintToChat ( client , " You are now not ignoring the racetimer " ) ;
}
else
{
g_bClientsIgnoring [ client ] = true ;
g_bHideTimer [ client ] = true ;
SetClientCookie ( client , g_hClientCookie , " 1 " ) ;
PrintToChat ( client , " You are now ignoring the racetimer " ) ;
}
char sSID [ g_dIndex ] ;
char sQuery [ g_dLength ] ;
GetClientAuthId ( client , AuthId_Steam2 , sSID , sizeof ( sSID ) ) ;
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
return ;
}
if ( StrEqual ( sSID , " STEAM_ID_STOP_IGNORING_RETVALS " ) | | StrEqual ( sSID , " STEAM_ID_PENDING " ) )
{
PrintToChat ( client , " Your steam ID is not working, not updating timer " ) ;
return ;
}
Format ( sQuery , sizeof ( sQuery ) , " INSERT INTO `zetimer_table_new_ignoring` (`steam_auth`, `is_ignoring`) VALUES ('%s', '%i') ON DUPLICATE KEY UPDATE `is_ignoring` = '%i' " , sSID , g_bClientsIgnoring [ client ] , g_bClientsIgnoring [ client ] ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
}
2019-03-02 15:17:41 +01:00
public Action cmd_timerCheckTop ( int client , int args )
{
CheckTop ( client , 0 , 0 ) ;
return Plugin_Handled ;
}
2022-05-07 14:20:26 +02:00
public void mysql_select_lowest_ordered ( int client , int index , int length_increase , Menu menu , int l_iPosition )
{
int l_iZoneCount = unloze_zoneCount ( ) ;
char sQuery [ g_dLength ] ;
if ( l_iZoneCount < 2 )
2022-08-09 01:39:41 +02:00
Format ( sQuery , sizeof ( sQuery ) , " select name, `%s` from `zetimer_table_new` where `%s` > 0 order by `%s` asc limit 10 " , g_cMapname , g_cMapname , g_cMapname ) ;
2022-05-07 14:20:26 +02:00
else
2022-08-09 01:39:41 +02:00
Format ( sQuery , sizeof ( sQuery ) , " select name, `%sS%i` from `zetimer_table_new` where `%sS%i` > 0 order by `%sS%i` asc limit 10 " , g_cMapname , index , g_cMapname , index , g_cMapname , index ) ;
2022-05-07 14:20:26 +02:00
//LogMessage("sQuery: %s", sQuery);
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteCell ( GetClientSerial ( client ) ) ;
hDataPack . WriteString ( sQuery ) ;
hDataPack . WriteCell ( index ) ;
hDataPack . WriteCell ( menu ) ;
hDataPack . WriteCell ( l_iPosition ) ;
hDataPack . WriteCell ( length_increase ) ;
g_dDatabase . Query ( SQL_Select_Top_Callback , sQuery , hDataPack ) ;
}
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckTop ( int client , int index , int autismstate )
{
2022-05-07 14:20:26 +02:00
int l_iZoneCount = unloze_zoneCount ( ) ;
if ( l_iZoneCount < 1 )
{
PrintToChat ( client , " No zones active on this map " ) ;
return ;
}
if ( ! autismstate )
{
CheckStagesOnMap ( client , 0 ) ;
return ;
}
mysql_select_lowest_ordered ( client , index , 0 , null , 0 ) ;
2019-03-02 15:17:41 +01:00
}
2021-01-26 19:49:43 +01:00
2021-02-28 23:47:41 +01:00
public void SQL_Select_Top_Callback ( Database db , DBResultSet results , const char [ ] error , DataPack data )
2019-03-02 15:17:41 +01:00
{
2022-05-07 14:20:26 +02:00
ResetPack ( data ) ;
int client_serial = data . ReadCell ( ) ;
char sQuery [ g_dLength ] ;
data . ReadString ( sQuery , sizeof ( sQuery ) ) ;
if ( ! db | | strlen ( error ) )
{
LogError ( " Query error 2: %s " , error ) ;
LogError ( " actual query: %s " , sQuery ) ;
delete data ;
delete results ;
return ;
}
int index = data . ReadCell ( ) ;
Menu menu = data . ReadCell ( ) ;
int l_iPosition = data . ReadCell ( ) ;
int length_increase = data . ReadCell ( ) ;
length_increase + + ;
delete data ;
int iclient ;
if ( ( iclient = GetClientFromSerial ( client_serial ) ) = = 0 )
2023-04-30 12:14:28 +02:00
{
delete results ;
2022-05-07 14:20:26 +02:00
return ;
2023-04-30 12:14:28 +02:00
}
2022-05-07 14:20:26 +02:00
//Player Name
char [ ] g_cPlayerName = new char [ MAX_NAME_LENGTH ] ;
char g_cContent [ g_dLength ] ;
if ( menu = = null )
{
menu = new Menu ( MenuHandler1 ) ;
menu . SetTitle ( " Maptimer: %s " , g_cMapname ) ;
}
if ( results ! = INVALID_HANDLE )
{
while ( results . RowCount > 0 & & results . FetchRow ( ) & & l_iPosition < 10 )
2021-01-26 19:49:43 +01:00
{
2022-05-07 14:20:26 +02:00
l_iPosition + + ;
results . FetchString ( 0 , g_cPlayerName , MAX_NAME_LENGTH ) ;
2022-08-09 01:39:41 +02:00
float fTime = results . FetchFloat ( 1 ) ;
Format ( g_cContent , sizeof ( g_cContent ) , " #%i: Time: %06.3f - %s " , l_iPosition , fTime , g_cPlayerName ) ;
2022-05-07 14:20:26 +02:00
menu . AddItem ( " -1 " , g_cContent , ITEMDRAW_DISABLED ) ;
2021-01-26 19:49:43 +01:00
}
2022-05-07 14:20:26 +02:00
delete results ;
if ( ! l_iPosition )
2021-01-26 19:49:43 +01:00
{
2022-05-07 14:20:26 +02:00
menu . AddItem ( " -1 " , " No results. Commands: !toptime !stages " , ITEMDRAW_DISABLED ) ;
}
else if ( l_iPosition < 10 )
{
//did 2 mins googling but found nothing about menus needing to be cleaned
mysql_select_lowest_ordered ( iclient , index , length_increase , menu , l_iPosition ) ;
return ;
2021-01-26 19:49:43 +01:00
}
2022-05-07 14:20:26 +02:00
menu . ExitButton = true ;
menu . Display ( iclient , 0 ) ;
}
2023-04-30 12:14:28 +02:00
delete results ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int MenuHandler1 ( Menu menu , MenuAction action , int param1 , int param2 )
{
if ( action = = MenuAction_End )
delete menu ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
2019-09-05 23:14:56 +02:00
//----------------------------------------------------------------------------------------------------
public Action Cmd_timeReset ( int client , int args )
{
if ( ! IsValidClient ( client ) )
2019-09-05 23:16:38 +02:00
return Plugin_Handled ;
2019-09-05 23:14:56 +02:00
if ( args ! = 2 )
{
ReplyToCommand ( client , " [SM] Usage cleantime <target> <course> " ) ;
return Plugin_Handled ;
}
char sTarget [ 65 ] , steam2 [ 64 ] ;
GetCmdArg ( 1 , sTarget , sizeof ( sTarget ) ) ;
int targetID = FindTarget ( client , sTarget , false ) ;
if ( targetID = = - 1 )
return Plugin_Handled ;
GetClientAuthId ( targetID , AuthId_Steam2 , steam2 , sizeof ( steam2 ) ) ;
GetCmdArg ( 2 , sTarget , sizeof ( sTarget ) ) ;
deleteClientTime ( steam2 , StringToInt ( sTarget ) ) ;
return Plugin_Handled ;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
2019-07-24 00:43:06 +02:00
public Action cmd_hideTimerHUD ( int client , int args )
{
if ( ! g_bHideTimer [ client ] )
{
g_bHideTimer [ client ] = true ;
2019-08-04 12:59:39 +02:00
SetClientCookie ( client , g_hClientCookie , " 1 " ) ;
2019-07-24 00:43:06 +02:00
PrintToChat ( client , " Disabled timer HUD " ) ;
2019-08-04 12:59:39 +02:00
} else { g_bHideTimer [ client ] = false ; PrintToChat ( client , " Enabled timer HUD " ) ; SetClientCookie ( client , g_hClientCookie , " 0 " ) ; }
2019-07-24 00:43:06 +02:00
}
//----------------------------------------------------------------------------------------------------
// 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 )
{
2022-08-15 01:47:05 +02:00
int l_iCount ;
int l_iZoneCount = unloze_zoneCount ( ) ;
Menu StageMenu = CreateMenu ( Stage_menu ) ;
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 )
{
l_iCount + + ;
Format ( l_cMenuContent , sizeof ( l_cMenuContent ) , " Stage: %i " , l_iCount ) ;
StageMenu . AddItem ( " " , l_cMenuContent ) ;
}
else
{
int zone_reached = 0 ;
for ( int Iterator = 0 ; Iterator < = l_iZoneCount ; Iterator + + )
{
char zoneIndexName [ 512 ] ;
ZoneNameBasedOnIndex ( Iterator , zoneIndexName ) ;
if ( StrContains ( zoneIndexName , " ZONE_PREFIX_RACE " ) > - 1 )
{
char local_c [ g_dLength ] ;
Format ( local_c , sizeof ( local_c ) , " %s " , zoneIndexName [ strlen ( " ZONE_PREFIX_RACE " ) + 1 ] ) ;
int prev = zone_reached ;
zone_reached = StringToInt ( local_c ) ;
if ( zone_reached = = prev )
{
continue ;
}
l_iCount + + ;
Format ( l_cMenuContent , sizeof ( l_cMenuContent ) , " Stage: %i " , l_iCount ) ;
StageMenu . AddItem ( " " , l_cMenuContent ) ;
}
}
}
StageMenu . ExitButton = true ;
StageMenu . Display ( client , 0 ) ;
2019-03-02 15:17:41 +01:00
}
2022-08-15 01:47:05 +02:00
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// 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:
//----------------------------------------------------------------------------------------------------
2019-09-05 23:14:56 +02:00
public void deleteClientTime ( char [ ] steam2 , int stage )
{
2023-04-30 12:14:28 +02:00
char l_cQuery [ g_dLength ] ;
int l_iZoneCount = unloze_zoneCount ( ) ;
if ( l_iZoneCount > 1 )
Format ( l_cQuery , sizeof ( l_cQuery ) , " UPDATE `zetimer_table_new` SET `%sS%i` = 0.000 WHERE steam_auth = '%s' " , g_cMapname , stage , steam2 ) ;
else
Format ( l_cQuery , sizeof ( l_cQuery ) , " UPDATE `zetimer_table_new` SET `%s` = 0.000 WHERE steam_auth = '%s' " , g_cMapname , steam2 ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( l_cQuery ) ;
g_dDatabase . Query ( SQL_FinishedQuery , l_cQuery , hDataPack , DBPrio_Normal ) ;
2019-09-05 23:14:56 +02:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2019-03-02 15:17:41 +01:00
public void Checkself ( int client )
{
2022-08-15 01:47:05 +02:00
int l_iZoneCount = unloze_zoneCount ( ) ;
char l_cQuery [ g_dLength ] ;
char l_cSID [ g_dIndex ] ;
GetClientAuthId ( client , AuthId_Steam2 , l_cSID , sizeof ( l_cSID ) ) ;
if ( l_iZoneCount < 1 )
{
PrintToChat ( client , " No zones active on this map " ) ;
return ;
}
if ( l_iZoneCount < 2 )
{
Format ( l_cQuery , sizeof ( l_cQuery ) , " SELECT name, `%s` FROM `zetimer_table_new` WHERE steam_auth = '%s' " , g_cMapname , l_cSID ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteCell ( GetClientSerial ( client ) ) ;
hDataPack . WriteString ( l_cQuery ) ;
g_dDatabase . Query ( SQL_CheckSelf , l_cQuery , hDataPack ) ;
}
else
CheckStagesOnMap ( client , 1 ) ;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// 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 ) ) ;
2022-08-09 01:39:41 +02:00
Format ( l_cQuery , sizeof ( l_cQuery ) , " SELECT name, `%sS%i` FROM `zetimer_table_new` WHERE steam_auth = '%s' " , g_cMapname , selection , l_cSID ) ;
2021-02-28 23:47:41 +01:00
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteCell ( GetClientSerial ( client ) ) ;
hDataPack . WriteString ( l_cQuery ) ;
g_dDatabase . Query ( SQL_CheckSelf , l_cQuery , hDataPack ) ;
2019-03-02 15:17:41 +01:00
}
2021-02-25 23:44:03 +01:00
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
2021-02-28 23:47:41 +01:00
public void SQL_CheckSelf ( Database db , DBResultSet results , const char [ ] error , DataPack data )
2019-03-02 15:17:41 +01:00
{
2022-08-09 01:39:41 +02:00
ResetPack ( data ) ;
int client_serial = data . ReadCell ( ) ;
if ( ! db | | strlen ( error ) )
{
char sQuery [ g_dLength ] ;
data . ReadString ( sQuery , sizeof ( sQuery ) ) ;
LogError ( " Query error 4: %s " , error ) ;
LogError ( " actual query: %s " , sQuery ) ;
delete data ;
2023-04-30 12:14:28 +02:00
delete results ;
2022-08-09 01:39:41 +02:00
return ;
}
delete data ;
char l_cMessageContent [ g_dLength ] ;
char [ ] l_cPlayerName = new char [ MAX_NAME_LENGTH ] ;
int iclient ;
if ( ( iclient = GetClientFromSerial ( client_serial ) ) = = 0 )
2023-04-30 12:14:28 +02:00
{
delete results ;
2022-08-09 01:39:41 +02:00
return ;
2023-04-30 12:14:28 +02:00
}
2022-08-09 01:39:41 +02:00
if ( results . RowCount & & results . FetchRow ( ) )
{
results . FetchString ( 0 , l_cPlayerName , MAX_NAME_LENGTH ) ;
float fTime = results . FetchFloat ( 1 ) ;
if ( fTime = = 0.0 )
2021-01-26 19:49:43 +01:00
{
2022-08-09 01:39:41 +02:00
CPrintToChat ( iclient , " You have no time yet! " ) ;
2023-04-30 12:14:28 +02:00
delete results ;
2022-08-09 01:39:41 +02:00
return ;
2021-01-26 19:49:43 +01:00
}
2022-08-09 01:39:41 +02:00
fTime + = 0.001 ;
Format ( l_cMessageContent , sizeof ( l_cMessageContent ) , " %06.3f - %s " , fTime , l_cPlayerName ) ;
CPrintToChat ( iclient , " Your best time: %s " , l_cMessageContent ) ;
}
else
CPrintToChat ( iclient , " You have no time yet! " ) ;
2023-04-30 12:14:28 +02:00
delete results ;
2019-03-02 15:17:41 +01:00
}
2021-01-26 19:49:43 +01:00
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
stock bool IsValidClient ( int client )
{
if ( client > 0 & & client < = MaxClients & & IsClientConnected ( client ) & & IsClientInGame ( client ) )
return true ;
return false ;
2021-01-26 19:49:43 +01:00
}