922 lines
34 KiB
SourcePawn
922 lines
34 KiB
SourcePawn
#pragma semicolon 1
|
|
#define DEBUG
|
|
#define PLUGIN_AUTHOR "jenz"
|
|
#define PLUGIN_VERSION "1.6"
|
|
#define g_dLength 256
|
|
#define g_dIndex 65
|
|
#include <sourcemod>
|
|
#include <colorvariables>
|
|
#include <clientprefs>
|
|
#include <unloze_zones>
|
|
#include <unloze_racetimer_specialmaps>
|
|
#include <unloze_racetimer_antizones>
|
|
#include <cstrike>
|
|
#include <sdktools>
|
|
#pragma newdecls required
|
|
char g_cMapname[g_dLength];
|
|
char g_cSpecialMapStart[g_dLength];
|
|
char g_cSpecialMapEnd[g_dLength];
|
|
static char g_sConfigzones[PLATFORM_MAX_PATH];
|
|
float g_fStartTime[MAXPLAYERS + 1];
|
|
char g_csTime_record[MAXPLAYERS + 1];
|
|
float g_fClientVectors[MAXPLAYERS + 1][3];
|
|
int g_iClientFrames[MAXPLAYERS + 1];
|
|
int g_iClientSpeedInterval[MAXPLAYERS + 1];
|
|
int g_iClientChecking[MAXPLAYERS + 1];
|
|
bool g_bDisplaySpecial;
|
|
bool g_bHumansAllowedTime[MAXPLAYERS + 1];
|
|
bool g_bHideTimer[MAXPLAYERS + 1];
|
|
bool g_bEventBool = false;
|
|
Handle g_hClientCookie = INVALID_HANDLE;
|
|
Database g_dDatabase;
|
|
Handle hText;
|
|
|
|
int player_stage[MAXPLAYERS + 1];
|
|
|
|
public Plugin myinfo =
|
|
{
|
|
name = "UNLOZE_racetimer_css",
|
|
author = PLUGIN_AUTHOR,
|
|
description = "tracers times on race maps",
|
|
version = PLUGIN_VERSION,
|
|
url = "www.unloze.com"
|
|
};
|
|
|
|
public void OnConfigsExecuted()
|
|
{
|
|
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnPluginStart()
|
|
{
|
|
//cmds
|
|
RegConsoleCmd("sm_toptime", cmd_timerCheckTop, "checking top 10");
|
|
RegConsoleCmd("sm_mytime", cmd_timerCheckSelf, "checking your personal time");
|
|
RegConsoleCmd("sm_stages", cmd_timerCheckStage, "Checking race stages");
|
|
RegConsoleCmd("sm_hidetimer", cmd_hideTimerHUD, "Hides timer HUD");
|
|
RegAdminCmd("sm_cleantime", Cmd_timeReset, ADMFLAG_GENERIC);
|
|
//hooks
|
|
HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
|
|
//HUD
|
|
hText = CreateHudSynchronizer();
|
|
//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);
|
|
OnClientPostAdminCheck(i);
|
|
}
|
|
OnMapStart();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void SQL_OnDatabaseConnect(Database db, const char[] error, any data)
|
|
{
|
|
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` (`steam_auth` VARCHAR(254) NOT NULL, `name` VARCHAR(254) NOT NULL, PRIMARY KEY (`steam_auth`))");
|
|
g_dDatabase.Query(SQL_OnConnectFinished, sQuery, _, DBPrio_High);
|
|
|
|
g_bDisplaySpecial = unloze_gBSpecialMapDisplay();
|
|
GetCurrentMap(g_cMapname, sizeof(g_cMapname));
|
|
startTimer();
|
|
}
|
|
|
|
public void SQL_OnConnectFinished(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if(!db || strlen(error))
|
|
{
|
|
LogError("Database error: %s", error);
|
|
return;
|
|
}
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
OnClientPostAdminCheck(i);
|
|
}
|
|
|
|
public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if (!db || strlen(error))
|
|
{
|
|
LogError("Query error: %s", error);
|
|
return;
|
|
}
|
|
int client;
|
|
if ((client = GetClientFromSerial(data)) == 0)
|
|
return;
|
|
if (results.RowCount && results.FetchRow())
|
|
results.FetchString(0, g_csTime_record[client], sizeof(g_csTime_record));
|
|
}
|
|
|
|
public void MYSQLCheckMapEntry()
|
|
{
|
|
int l_iRaceCount;
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
char sQuery[g_dLength];
|
|
char l_cZoneIndexName[g_dIndex][g_dLength];
|
|
if (l_iZoneCount < 2)
|
|
{
|
|
Format(sQuery, sizeof(sQuery), "SELECT `%s` FROM `zetimer_table` LIMIT 1", g_cMapname);
|
|
g_dDatabase.Query(SQL_OnQueryCompleted1, sQuery, _);
|
|
}
|
|
else
|
|
for (int iterator = 0; iterator <= l_iZoneCount; iterator++)
|
|
{
|
|
if (IsCorrectZone(iterator, l_cZoneIndexName[iterator][g_dLength -1], "ZONE_PREFIX_RACE"))
|
|
{
|
|
l_iRaceCount++;
|
|
Format(sQuery, sizeof(sQuery), "SELECT `%sS%i` FROM `zetimer_table` LIMIT 1", g_cMapname, l_iRaceCount);
|
|
g_dDatabase.Query(SQL_OnQueryCompleted1, sQuery, _);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SQL_OnQueryCompleted1(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if (!db)
|
|
{
|
|
LogError("Query error: %s", error);
|
|
return;
|
|
}
|
|
int l_iRaceCount;
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
char sQuery[g_dLength];
|
|
char l_cZoneIndexName[g_dIndex][g_dLength];
|
|
if (results == null)
|
|
{
|
|
if (l_iZoneCount == 1)
|
|
{
|
|
Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table` ADD COLUMN `%s` VARCHAR(256) DEFAULT '0.000' NOT NULL", g_cMapname);
|
|
g_dDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_High);
|
|
}
|
|
else
|
|
{
|
|
//this might seem repetitive but one null check adds all required coloumns
|
|
for (int iterator = 0; iterator <= l_iZoneCount; iterator++)
|
|
{
|
|
if (IsCorrectZone(iterator, l_cZoneIndexName[iterator][g_dLength -1], "ZONE_PREFIX_RACE"))
|
|
{
|
|
l_iRaceCount++;
|
|
Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table` ADD COLUMN `%sS%i` VARCHAR(256) DEFAULT '0.000' NOT NULL", g_cMapname, l_iRaceCount);
|
|
g_dDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_High);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SQL_FinishedQuery(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if (!db || strlen(error))
|
|
{
|
|
LogError("Query error: %s", error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
public void SQL_FinishedQuery_mute_error(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if (!db)
|
|
return;
|
|
}
|
|
|
|
public void OnMapStart()
|
|
{
|
|
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;
|
|
AutoExecConfig();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnPluginEnd()
|
|
{
|
|
CloseHandle(hText);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
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)
|
|
{
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
if (!l_iZoneCount)
|
|
return;
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
if (IsValidClient(i))
|
|
{
|
|
resetClientVectors(i);
|
|
if (l_iZoneCount != 1)
|
|
g_bHumansAllowedTime[i] = false;
|
|
else
|
|
{
|
|
mysql_get_player_time(i, 0);
|
|
g_bHumansAllowedTime[i] = true;
|
|
g_fStartTime[i] = GetEngineTime();
|
|
}
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientPostAdminCheck(int client)
|
|
{
|
|
resetClient(client);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientCookiesCached(int client)
|
|
{
|
|
char sValue[8];
|
|
GetClientCookie(client, g_hClientCookie, sValue, sizeof(sValue));
|
|
g_bHideTimer[client] = (sValue[0] != '\0' && !!StringToInt(sValue));
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientDisconnect(int client)
|
|
{
|
|
resetClient(client);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void resetClient(int client)
|
|
{
|
|
if (IsClientConnected(client) && IsClientAuthorized(client))
|
|
{
|
|
g_iClientChecking[client] = 0;
|
|
g_bHumansAllowedTime[client] = false;
|
|
resetClientVectors(client);
|
|
player_stage[client] = 0;
|
|
Format(g_csTime_record[client], sizeof(g_csTime_record[]), "0.000");
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
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])
|
|
{
|
|
if (!IsValidClient(client))
|
|
return;
|
|
if (g_bEventBool)
|
|
{
|
|
g_bHumansAllowedTime[client] = false;
|
|
return;
|
|
}
|
|
|
|
if (g_bHumansAllowedTime[client] && (GetClientTeam(client) == CS_TEAM_CT) && IsPlayerAlive(client))
|
|
{
|
|
int frameCap = 11;
|
|
if (g_iClientFrames[client] >= frameCap)
|
|
{
|
|
g_iClientFrames[client] = 0;
|
|
float clientVectors[3];
|
|
GetClientAbsOrigin(client, clientVectors);
|
|
if (checkClientOrigin(g_fClientVectors[client], clientVectors, client))
|
|
{
|
|
g_bHumansAllowedTime[client] = false;
|
|
resetClientVectors(client);
|
|
PrintToChat(client, "Disabled timer due to potential teleport abuse");
|
|
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;
|
|
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;
|
|
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;
|
|
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);
|
|
char sTime[32];
|
|
FormatPlayerTime(total_time, sTime, sizeof(sTime), false, 1);
|
|
ShowSyncHudText(client, hText, "%N Time: %s\nRecord: %s\nMap: %s\nCourse: %i", client, sTime, g_csTime_record[client], g_cMapname, player_stage[client]);
|
|
}
|
|
}
|
|
g_iClientSpeedInterval[client]++;
|
|
}
|
|
g_iClientFrames[client]++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
public float client_current_race_time(int i_client)
|
|
{
|
|
return GetEngineTime() - g_fStartTime[i_client];
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void resetClientVectors(int client)
|
|
{
|
|
if (IsClientConnected(client) && IsClientAuthorized(client))
|
|
{
|
|
g_fClientVectors[client][0] = 0.000000;
|
|
g_fClientVectors[client][1] = 0.000000;
|
|
g_fClientVectors[client][2] = 0.000000;
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public bool checkClientOrigin(float oldVals[3], float newVals[3], int client)
|
|
{
|
|
float zero = 0.000000;
|
|
if ((oldVals[0] == zero && oldVals[1] == zero && oldVals[2] == zero) || (newVals[0] == zero && newVals[1] == zero && newVals[2] == zero))
|
|
{
|
|
return false;
|
|
}
|
|
float teleport_range = 9000000.0;
|
|
int velocityCap = 625;
|
|
float distance = GetVectorDistance(oldVals, newVals, true);
|
|
//PrintToChatAll("distance: %f", distance);
|
|
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;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void unloze_zoneEntry(int client, char[] zone)
|
|
{
|
|
int zoneIndex = RetrieveZoneIndex(zone);
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
if (((GetClientTeam(client) == CS_TEAM_CT && g_bHumansAllowedTime[client]) && StrContains(zone, "ZONE_PREFIX_RACE") > -1) || StrEqual(zone, g_cSpecialMapEnd))
|
|
{
|
|
if (IsClientAuthorized(client))
|
|
{
|
|
if (l_iZoneCount < 2)
|
|
player_stage[client] = 0;
|
|
if (player_stage[client] == (zoneIndex / 2) || l_iZoneCount < 2)
|
|
FinishedStageRaceZone(client);
|
|
}
|
|
else
|
|
PrintToChat(client, "You are not authorized with steam!!");
|
|
g_bHumansAllowedTime[client] = false;
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void unloze_zoneLeave(int client, char[] zone)
|
|
{
|
|
//only maps with multiple zones need ZONE_PREFIX_START
|
|
if (((GetClientTeam(client) == CS_TEAM_CT) && StrContains(zone, "ZONE_PREFIX_START") > -1) || StrEqual(zone, g_cSpecialMapStart))
|
|
{
|
|
resetClientVectors(client);
|
|
g_fStartTime[client] = GetEngineTime();
|
|
float notRounded = float(RetrieveZoneIndex(zone));
|
|
player_stage[client] = RoundToCeil(notRounded / 2);
|
|
mysql_get_player_time(client, player_stage[client]);
|
|
g_bHumansAllowedTime[client] = true;
|
|
CPrintToChat(client, "Timer started for Course: %i", player_stage[client]);
|
|
}
|
|
}
|
|
|
|
stock void FormatPlayerTime(float Time, char[] result, int maxlength, bool showDash, int precision)
|
|
{
|
|
if(Time <= 0.0 && showDash == true)
|
|
{
|
|
Format(result, maxlength, "-");
|
|
return;
|
|
}
|
|
int hours = RoundToFloor(Time/3600);
|
|
Time -= hours*3600;
|
|
int minutes = RoundToFloor(Time/60);
|
|
Time -= minutes*60;
|
|
float seconds = Time;
|
|
|
|
char sPrecision[16];
|
|
|
|
if(precision == 0)
|
|
Format(sPrecision, sizeof(sPrecision), (hours > 0 || minutes > 0)?"%04.1f":"%.1f", seconds);
|
|
else if(precision == 1)
|
|
Format(sPrecision, sizeof(sPrecision), (hours > 0 || minutes > 0)?"%06.3f":"%.3f", seconds);
|
|
else if(precision == 2)
|
|
Format(sPrecision, sizeof(sPrecision), (hours > 0 || minutes > 0)?"%09.6f":"%.6f", seconds);
|
|
|
|
if(hours > 0)
|
|
Format(result, maxlength, "%d:%02d:%s", hours, minutes, sPrecision);
|
|
else if(minutes > 0)
|
|
Format(result, maxlength, "%d:%s", minutes, sPrecision);
|
|
else
|
|
Format(result, maxlength, "%s", sPrecision);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void unloze_zoneCreated()
|
|
{
|
|
startTimer();
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void CheckIfSpecialRoundZones(char[] resultstart, char[] resultend)
|
|
{
|
|
Format(g_cSpecialMapStart, sizeof(g_cSpecialMapStart), resultstart);
|
|
Format(g_cSpecialMapEnd, sizeof(g_cSpecialMapEnd), resultend);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void CheckifAntiZones(int client, bool reset)
|
|
{
|
|
if (reset)
|
|
g_bHumansAllowedTime[client] = false;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// 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;
|
|
if (iterator == -1)
|
|
return 1;
|
|
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]);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void FinishedStageRaceZone(int client)
|
|
{
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
char record_client[32];
|
|
Format(record_client, sizeof(record_client), g_csTime_record[client]);
|
|
float client_time = client_current_race_time(client);
|
|
char sTime[32];
|
|
FormatPlayerTime(client_time, sTime, sizeof(sTime), false, 1);
|
|
float old_record = StringToFloat(record_client);
|
|
float new_time = StringToFloat(sTime);
|
|
|
|
if (l_iZoneCount > 1)
|
|
CPrintToChat(client, "{green}[UNLOZE] Stage: %i", player_stage[client]);
|
|
CPrintToChat(client, "{green}[UNLOZE] Client: %N Time: %s", client, sTime);
|
|
|
|
if (old_record == 0.0)
|
|
{
|
|
CPrintToChat(client, "Your record: None yet\nCommand: !toptime !mytime !stages");
|
|
sendMYSQL(client, sTime, player_stage[client]);
|
|
return;
|
|
}
|
|
CPrintToChat(client, "Your record: %s\nCommand: !toptime !mytime !stages", record_client);
|
|
if (new_time < old_record)
|
|
sendMYSQL(client, sTime, player_stage[client]);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// 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` where steam_auth = '%s'", g_cMapname, steam_auth);
|
|
else
|
|
Format(query, sizeof(query), "SELECT `%sS%i` FROM `zetimer_table` where steam_auth = '%s'", g_cMapname, stage, steam_auth);
|
|
g_dDatabase.Query(SQL_OnQueryCompleted, query, GetClientSerial(client));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// 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++)
|
|
{
|
|
ZoneNameBasedOnIndex(iterator, l_cIndexName[iterator]);
|
|
if (StrContains(l_cIndexName[iterator], "ZONE_PREFIX_RACE") > -1)
|
|
l_iCountRace++;
|
|
}
|
|
return l_iCountRace;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void sendMYSQL(int client, char[] sTime, int stage)
|
|
{
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
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];
|
|
|
|
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;
|
|
}
|
|
if (l_iZoneCount < 2)
|
|
{
|
|
Format(sQuery, sizeof(sQuery), "INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%s`) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE `name` = '%s', `%s` = '%s'", g_cMapname, sSID, sEscapedName, sTime, sEscapedName, g_cMapname, sTime);
|
|
}
|
|
else
|
|
{
|
|
Format(sQuery, sizeof(sQuery), "INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%sS%i`) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE `name` = '%s', `%sS%i` = '%s'", g_cMapname, stage, sSID, sEscapedName, sTime, sEscapedName, g_cMapname, stage, sTime);
|
|
}
|
|
g_dDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_High);
|
|
CPrintToChat(client, "Updated timer");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action cmd_timerCheckTop(int client, int args)
|
|
{
|
|
CheckTop(client, 0, 0);
|
|
return Plugin_Handled;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void CheckTop(int client, int index, int autismstate)
|
|
{
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
char sQuery[g_dLength];
|
|
//PrintToChatAll("checktop l_iZoneCount: %i", l_iZoneCount);
|
|
if (l_iZoneCount < 1)
|
|
{
|
|
PrintToChat(client, "No zones active on this map");
|
|
return;
|
|
}
|
|
if (!autismstate)
|
|
{
|
|
CheckStagesOnMap(client, 0);
|
|
return;
|
|
}
|
|
//we have index now from menu selection
|
|
if (l_iZoneCount < 2)
|
|
Format(sQuery, sizeof(sQuery), "SELECT name, `%s` FROM `zetimer_table` WHERE `%s` != 0.000 ORDER BY `%s` * 1 ASC LIMIT 10", g_cMapname, g_cMapname, g_cMapname);
|
|
else
|
|
Format(sQuery, sizeof(sQuery), "SELECT name, `%sS%i` FROM `zetimer_table` WHERE `%sS%i` != 0.000 ORDER BY `%sS%i` * 1 ASC LIMIT 10", g_cMapname, index, g_cMapname, index, g_cMapname, index);
|
|
g_dDatabase.Query(SQL_Select_Top_Callback, sQuery, GetClientSerial(client));
|
|
}
|
|
|
|
public void SQL_Select_Top_Callback(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if(!db || strlen(error))
|
|
{
|
|
LogError("Database error: %s", error);
|
|
return;
|
|
}
|
|
int iclient;
|
|
if ((iclient = GetClientFromSerial(data)) == 0)
|
|
return;
|
|
int l_iPosition;
|
|
char sTime[g_dLength];
|
|
//Player Name
|
|
char[] g_cPlayerName = new char[MAX_NAME_LENGTH];
|
|
char g_cContent[g_dLength];
|
|
Menu menu = new Menu(MenuHandler1);
|
|
menu.SetTitle("Maptimer: %s", g_cMapname);
|
|
if (results != INVALID_HANDLE)
|
|
{
|
|
while (results.RowCount > 0 && results.FetchRow())
|
|
{
|
|
l_iPosition++;
|
|
results.FetchString(0, g_cPlayerName, MAX_NAME_LENGTH);
|
|
results.FetchString(1, sTime, sizeof(sTime));
|
|
Format(g_cContent, sizeof(g_cContent), "#%i: Time: %s - %s", l_iPosition, sTime, g_cPlayerName);
|
|
menu.AddItem("-1", g_cContent, ITEMDRAW_DISABLED);
|
|
}
|
|
if (!l_iPosition)
|
|
{
|
|
menu.AddItem("-1", "No results. Commands: !toptime !stages", ITEMDRAW_DISABLED);
|
|
}
|
|
menu.ExitButton = true;
|
|
menu.Display(iclient, 0);
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)
|
|
{
|
|
if (action == MenuAction_End)
|
|
delete menu;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action Cmd_timeReset(int client, int args)
|
|
{
|
|
if (!IsValidClient(client))
|
|
return Plugin_Handled;
|
|
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:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action cmd_hideTimerHUD(int client, int args)
|
|
{
|
|
if (!g_bHideTimer[client])
|
|
{
|
|
g_bHideTimer[client] = true;
|
|
SetClientCookie(client, g_hClientCookie, "1");
|
|
PrintToChat(client, "Disabled timer HUD");
|
|
} else { g_bHideTimer[client] = false; PrintToChat(client, "Enabled timer HUD"); SetClientCookie(client, g_hClientCookie, "0"); }
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action cmd_timerCheckStage(int client, int args)
|
|
{
|
|
CheckStagesOnMap(client, 0);
|
|
return Plugin_Handled;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void CheckStagesOnMap(int client, int state)
|
|
{
|
|
int l_iCount;
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
Menu StageMenu = CreateMenu(Stage_menu);
|
|
char l_cZoneIndexName[g_dIndex][g_dLength];
|
|
char l_cMenuContent[g_dLength];
|
|
if (!l_iZoneCount)
|
|
{
|
|
CPrintToChat(client, "[UNLOZE] Map does not support racestage timer");
|
|
return;
|
|
}
|
|
//state 0 == toptime, state 1 == own time
|
|
g_iClientChecking[client] = state;
|
|
StageMenu.SetTitle("Stages on: %s", g_cMapname);
|
|
if (g_bDisplaySpecial)
|
|
{
|
|
l_iCount++;
|
|
Format(l_cMenuContent, sizeof(l_cMenuContent), "Stage: %i", l_iCount);
|
|
StageMenu.AddItem("", l_cMenuContent);
|
|
}
|
|
else
|
|
{
|
|
for (int Iterator = 0; Iterator <= l_iZoneCount; Iterator++)
|
|
{
|
|
if (IsCorrectZone(Iterator, l_cZoneIndexName[Iterator][g_dLength -1], "ZONE_PREFIX_RACE"))
|
|
{
|
|
l_iCount++;
|
|
Format(l_cMenuContent, sizeof(l_cMenuContent), "Stage: %i", l_iCount);
|
|
StageMenu.AddItem("", l_cMenuContent);
|
|
}
|
|
}
|
|
}
|
|
StageMenu.ExitButton = true;
|
|
StageMenu.Display(client, 0);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public bool IsCorrectZone(int index, char[] zoneIndexName, char[] zone_prefix)
|
|
{
|
|
ZoneNameBasedOnIndex(index, zoneIndexName);
|
|
if (StrContains(zoneIndexName, zone_prefix) > -1)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int Stage_menu(Menu menu, MenuAction action, int client, int selection)
|
|
{
|
|
if (action == MenuAction_Select && IsValidClient(client))
|
|
{
|
|
selection++;
|
|
if (!g_iClientChecking[client])
|
|
{
|
|
CheckTop(client, selection, 1);
|
|
}
|
|
else
|
|
{
|
|
CheckStageSelf(client, selection);
|
|
}
|
|
}
|
|
else if (action == MenuAction_End)
|
|
{
|
|
delete(menu);
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action cmd_timerCheckSelf(int client, int args)
|
|
{
|
|
Checkself(client);
|
|
return Plugin_Handled;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void deleteClientTime(char[] steam2, int stage)
|
|
{
|
|
char l_cQuery[g_dLength];
|
|
if (stage > 1)
|
|
{
|
|
Format(l_cQuery, sizeof(l_cQuery), "UPDATE `zetimer_table` SET `%sS%i` = '0.000' WHERE steam_auth = '%s'", g_cMapname, stage, steam2);
|
|
}
|
|
else
|
|
{
|
|
Format(l_cQuery, sizeof(l_cQuery), "UPDATE `zetimer_table` SET `%s` = '0.000' WHERE steam_auth = '%s'", g_cMapname, steam2);
|
|
g_dDatabase.Query(SQL_FinishedQuery, l_cQuery, _, DBPrio_High);
|
|
Format(l_cQuery, sizeof(l_cQuery), "UPDATE `zetimer_table` SET `%sS1` = '0.000' WHERE steam_auth = '%s'", g_cMapname, steam2);
|
|
}
|
|
g_dDatabase.Query(SQL_FinishedQuery_mute_error, l_cQuery, _, DBPrio_High);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void Checkself(int client)
|
|
{
|
|
int l_iZoneCount = unloze_zoneCount();
|
|
char l_cQuery[g_dLength];
|
|
char l_cSID[g_dIndex];
|
|
GetClientAuthId(client, AuthId_Steam2, l_cSID, sizeof(l_cSID));
|
|
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` WHERE steam_auth = '%s'", g_cMapname, l_cSID);
|
|
g_dDatabase.Query(SQL_CheckSelf, l_cQuery, GetClientSerial(client));
|
|
}
|
|
else
|
|
CheckStagesOnMap(client, 1);
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void CheckStageSelf(int client, int selection)
|
|
{
|
|
char l_cQuery[g_dLength];
|
|
char l_cSID[g_dIndex];
|
|
GetClientAuthId(client, AuthId_Steam2, l_cSID, sizeof(l_cSID));
|
|
Format(l_cQuery, sizeof(l_cQuery), "SELECT name, `%sS%i` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, selection, l_cSID);
|
|
g_dDatabase.Query(SQL_CheckSelf, l_cQuery, GetClientSerial(client));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void SQL_CheckSelf(Database db, DBResultSet results, const char[] error, any data)
|
|
{
|
|
if(!db || strlen(error))
|
|
{
|
|
LogError("Database error: %s", error);
|
|
return;
|
|
}
|
|
char sTime[g_dLength];
|
|
char l_cMessageContent[g_dLength];
|
|
char[] l_cPlayerName = new char[MAX_NAME_LENGTH];
|
|
int iclient;
|
|
if ((iclient = GetClientFromSerial(data)) == 0)
|
|
return;
|
|
if (results.RowCount && results.FetchRow())
|
|
{
|
|
results.FetchString(0, l_cPlayerName, MAX_NAME_LENGTH);
|
|
results.FetchString(1, sTime, sizeof(sTime));
|
|
if (StrEqual(sTime, "0.000", false))
|
|
{
|
|
CPrintToChat(iclient, "You have no time yet!");
|
|
return;
|
|
}
|
|
Format(l_cMessageContent, sizeof(l_cMessageContent), "%s - %s", sTime, l_cPlayerName);
|
|
CPrintToChat(iclient, "Your best time: 0%s", l_cMessageContent);
|
|
}
|
|
else
|
|
CPrintToChat(iclient, "You have no time yet!");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
stock bool IsValidClient(int client)
|
|
{
|
|
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
|
|
return true;
|
|
return false;
|
|
}
|