projects-jenz/RaceTimer/scripting/unloze_racetimer_redux.sp

1342 lines
50 KiB
SourcePawn
Raw Normal View History

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"
#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];
char g_csTime_record[MAXPLAYERS + 1][65];
float g_fClientVectors[MAXPLAYERS + 1][3];
float g_fClient_End_time[MAXPLAYERS + 1];
int g_iClientFrames[MAXPLAYERS + 1];
int g_iClientSpeedInterval[MAXPLAYERS + 1];
2019-03-02 15:17:41 +01:00
int g_iClientChecking[MAXPLAYERS + 1];
bool g_bClientsIgnoring[MAXPLAYERS + 1];
2019-03-02 15:17:41 +01:00
bool g_bDisplaySpecial;
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;
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;
Handle hText;
int player_stage[MAXPLAYERS + 1];
Handle g_hAlterTableTimer = null;
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");
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);
//DB
if (!g_dDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
}
2022-08-09 01:39:41 +02:00
//HUD
hText = CreateHudSynchronizer();
//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);
}
g_bDisplaySpecial = unloze_gBSpecialMapDisplay();
2019-08-04 12:59:39 +02:00
}
2021-02-25 23:44:03 +01:00
public Action allow_leaving_again(Handle hTimer, int Serial)
{
int client;
if ((client = GetClientFromSerial(Serial)) == 0)
{
return;
}
if (IsValidClient(client))
{
g_bClient_allowed_to_leave_again[client] = true;
}
}
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)
{
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.");
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;
g_bhumans_finished[client] = false;
2022-08-09 01:39:41 +02:00
resetClientVectors(client);
g_bClient_allowed_to_leave_again[client] = false;
PrintToChat(client, "Disabled timer due to potential teleport abuse, type 1.");
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:
//----------------------------------------------------------------------------------------------------
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`))");
g_dDatabase.Query(SQL_OnConnectFinished, sQuery, _, DBPrio_Normal);
2021-02-25 23:44:03 +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))
{
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)
{
delete results;
2022-08-09 01:39:41 +02:00
return;
}
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();
2022-08-09 01:39:41 +02:00
for(int i = 1; i <= MaxClients; i++)
if (IsValidClient(i))
OnClientPostAdminCheck(i);
AddBinarySearchIndex();
delete results;
}
2021-02-25 23:44:03 +01:00
public void MYSQLCheckMapEntry()
{
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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
}
else
{
for (int iterator = 0; iterator <= l_iZoneCount; iterator++)
{
char zoneIndexName[512];
ZoneNameBasedOnIndex(iterator, zoneIndexName);
if (StrContains(zoneIndexName, "ZONE_PREFIX_RACE") > -1)
{
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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
}
}
}
}
public void SQL_FinishedQuery(Database db, DBResultSet results, const char[] error, DataPack data)
{
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;
}
//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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
}
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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
}
}
}
//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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
}
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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
}
}
}
public void OnMapEnd()
{
if (!g_dDatabase)
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
else
RemoveBinarySearchIndex();
}
public void OnMapStart()
{
if (!g_dDatabase)
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
else
{
AddBinarySearchIndex();
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), "");
}
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginEnd()
{
CloseHandle(hText);
if (g_hAlterTableTimer != null)
delete g_hAlterTableTimer;
RemoveBinarySearchIndex();
}
//----------------------------------------------------------------------------------------------------
// 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)
{
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();
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;
g_fClient_End_time[i] = 0.0;
2022-08-02 14:27:20 +02:00
resetClientVectors(i);
char first_zone[512];
ZoneNameBasedOnIndex(0, first_zone);
g_bClient_allowed_to_leave_again[i] = true;
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();
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)
{
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);
g_dDatabase.Query(SQL_OnQueryCompleted_ignoring, query, GetClientSerial(client));
}
public void SQL_OnQueryCompleted_ignoring(Database db, DBResultSet results, const char[] error, int Serial)
{
if (!db)
{
delete results;
return;
}
int client;
if ((client = GetClientFromSerial(Serial)) == 0)
{
delete results;
return;
}
if (!IsValidClient(client))
{
delete results;
return;
}
int val = 0;
if (results.RowCount && results.FetchRow())
val = results.FetchInt(0);
g_bClientsIgnoring[client] = false;
if (val == 1)
{
g_bClientsIgnoring[client] = true;
}
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;
g_bClientsIgnoring[client] = false;
2022-08-02 14:27:20 +02:00
g_bHumansAllowedTime[client] = false;
g_bhumans_finished[client] = false;
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");
}
}
//----------------------------------------------------------------------------------------------------
// 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])
{
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;
PrintToChat(client, "Disabling timer due to map being marked as event map.");
2022-08-09 01:39:41 +02:00
return;
}
if (!IsPlayerAlive(client))
2022-08-02 14:27:20 +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.");
CreateTimer(1.0, allow_leaving_again, GetClientSerial(client));
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\nRecord: %s\nMap: %s\nCourse: %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]++;
}
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];
}
2021-02-25 23:44:03 +01: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;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public bool checkClientOrigin(float oldVals[3], float newVals[3], int client)
{
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;
int velocityCap = 625;
float distance = GetVectorDistance(oldVals, newVals, true);
bool bInAir = (GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") == -1);
if (distance > teleport_range)
{
if (StrContains(g_cMapname, "surf", false) != -1)
return false;
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)
return false;
return true;
}
return false;
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void unloze_zoneEntry(int client, char[] zone)
{
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();
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();
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;
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
if (g_bClientsIgnoring[client])
{
return;
}
2022-08-09 01:39:41 +02:00
int race_zone_count = GetTotalRaceZones();
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
}
if (!g_bClient_allowed_to_leave_again[client])
{
PrintToChat(client, "Did not start timer due to teleport cooldown.");
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]);
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)
{
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)
{
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
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);
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];
2022-08-09 01:39:41 +02:00
g_dDatabase.Escape(sName, sEscapedName, size2 + 1);
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;
}
2022-08-09 01:39:41 +02:00
int l_iZoneCount = unloze_zoneCount();
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]);
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"))
{
CPrintToChat(client, "{green}[UNLOZE] Your record: None yet\nCommand: !toptime !mytime !stages");
2022-08-09 01:39:41 +02:00
}
else
{
CPrintToChat(client, "{green}[UNLOZE] Your record: %s\nCommand: !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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
2019-03-02 15:17:41 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void mysql_get_player_time(int client, int stage)
{
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));
hDataPack.WriteString(query);
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)
{
delete results;
return;
}
int client;
if ((client = GetClientFromSerial(client_serial)) == 0)
{
delete results;
return;
}
if (strlen(error))
{
delete results;
mysql_get_player_time(client, 1);
return;
}
if (results.RowCount && results.FetchRow())
results.FetchString(0, g_csTime_record[client], sizeof(g_csTime_record[]));
delete results;
}
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;
delete results;
2022-08-09 01:39:41 +02:00
return;
}
delete data;
int client;
if ((client = GetClientFromSerial(client_serial)) == 0)
{
delete results;
2022-08-09 01:39:41 +02:00
return;
}
2022-08-09 01:39:41 +02:00
if (results.RowCount && results.FetchRow())
results.FetchString(0, g_csTime_record[client], sizeof(g_csTime_record[]));
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;
for (int iterator = 0; iterator < l_iZoneCount; iterator++)
2019-03-02 15:17:41 +01: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:
//----------------------------------------------------------------------------------------------------
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);
g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_Normal);
2019-03-02 15:17:41 +01:00
}
2019-03-02 15:17:41 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
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;
}
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);
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);
//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)
{
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
}
public void SQL_Select_Top_Callback(Database db, DBResultSet results, const char[] error, DataPack data)
2019-03-02 15:17:41 +01: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)
{
delete results;
return;
}
//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)
{
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);
menu.AddItem("-1", g_cContent, ITEMDRAW_DISABLED);
}
delete results;
if (!l_iPosition)
{
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;
}
menu.ExitButton = true;
menu.Display(iclient, 0);
}
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)
{
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
}
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)
{
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)
{
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);
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:
//----------------------------------------------------------------------------------------------------
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;
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)
{
delete results;
2022-08-09 01:39:41 +02:00
return;
}
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)
{
2022-08-09 01:39:41 +02:00
CPrintToChat(iclient, "You have no time yet!");
delete results;
2022-08-09 01:39:41 +02:00
return;
}
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!");
delete results;
2019-03-02 15:17:41 +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;
}