#pragma semicolon 1 #define DEBUG #define PLUGIN_AUTHOR "jenz" #define PLUGIN_VERSION "1.4" #define g_dLength 256 #define g_dIndex 65 #include #include #include #include #include #include #include #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_fRoundMinutes; float g_fRoundSeconds; float g_fMinutesIndividual[MAXPLAYERS + 1]; float g_fSecondsIndividual[MAXPLAYERS + 1]; float g_fRecordSeconds[g_dIndex + 1][100]; int g_iRecordMinutes[g_dIndex + 1][100]; //100 because we have a total of 53 race zones right now int g_iRaceCount[MAXPLAYERS + 1]; int g_iTableCountID; //testing int g_iClientStage[MAXPLAYERS + 1]; int g_iClientChecking[MAXPLAYERS + 1]; bool g_bMessage[g_dIndex + 1][MAXPLAYERS + 1]; bool g_bDisplaySpecial; bool g_bRecentTimes[MAXPLAYERS + 1]; Database g_dDatabase; public Plugin myinfo = { name = "UNLOZE_racetimer_css", author = PLUGIN_AUTHOR, description = "tracers times on race maps", version = PLUGIN_VERSION, url = "www.unloze.com" }; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginStart() { //cmds RegConsoleCmd("sm_toptime", cmd_timerCheckTop, "checking top 10"); RegConsoleCmd("sm_mytime", cmd_timerCheckSelf, "checking your personal time"); RegConsoleCmd("sm_stages", cmd_timerCheckStage, "Checking race stages"); RegAdminCmd("sm_threadtestresult", cmd_threadtest, ADMFLAG_BAN); //hooks HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnMapStart() { //mysql placed here just in case somebody wants to reset database without having to reload plugin g_bDisplaySpecial = unloze_gBSpecialMapDisplay(); SQL_StartConnection(); GetCurrentMap(g_cMapname, sizeof(g_cMapname)); CreateTimer(0.1, Timer_CountdownRace, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); startTimer(); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void startTimer() { char line[g_dLength]; Handle zonefile = INVALID_HANDLE; BuildPath(Path_SM, g_sConfigzones, sizeof(g_sConfigzones), "configs/unloze_zones/%s.zones.txt", g_cMapname); zonefile = OpenFile(g_sConfigzones, "r"); if (zonefile != INVALID_HANDLE) { while (!IsEndOfFile(zonefile) && ReadFileLine(zonefile, line, sizeof(line))) { if (StrContains(line, "ZONE_PREFIX_RACE", false) > -1 || g_bDisplaySpecial) { MYSQLCheckMapEntry(); break; } } } delete zonefile; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Timer_CountdownRace(Handle timer, any data) { g_fRoundSeconds += 0.1; if (g_fRoundSeconds >= 60.0) { g_fRoundMinutes += 1.0; g_fRoundSeconds = 0.0; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast) { g_fRoundMinutes = 0.0; g_fRoundSeconds = 0.0; int l_iRaceZoneCount = GetTotalRaceZones(); for (int i = 1; i <= MaxClients; i++) if (IsValidClient(i)) { MYSQLCheckRecord(i); for (int j = 0; j <= l_iRaceZoneCount; j++) g_bMessage[i][j] = false; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPostAdminCheck(int client) { resetClient(client); MYSQLCheckRecord(client); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientDisconnect(int client) { resetClient(client); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void resetClient(int client) { int l_iRaceZoneCount = GetTotalRaceZones(); for (int j = 0; j <= l_iRaceZoneCount; j++) g_bMessage[client][j] = false; g_bRecentTimes[client] = false; g_fSecondsIndividual[client] = 0.0; g_fMinutesIndividual[client] = 0.0; g_iClientChecking[client] = 0; g_iClientStage[client] = 0; for (int i = 0; i < 100; i++) { g_iRecordMinutes[client][i] = 0; g_fRecordSeconds[client][i] = 0.0; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void unloze_zoneEntry(int client, char[] zone) { int l_iZoneIndex = RetrieveZoneIndex(zone); int l_iZoneCount = unloze_zoneCount(); if (((GetClientTeam(client) == CS_TEAM_CT) && StrContains(zone, "ZONE_PREFIX_RACE") > -1) || StrEqual(zone, g_cSpecialMapEnd)) { /* PrintToChatAll("g_bMessage: %i", g_bMessage[client][g_iClientStage[client]]); PrintToChatAll("g_iClientStage[client]: %i", g_iClientStage[client]); PrintToChatAll("(l_iZoneIndex / 2 )-1: %i", (l_iZoneIndex / 2) -1); */ if (l_iZoneCount < 2 && !g_bMessage[client][0]) { g_iClientStage[client] = 0; MYSQLCheckRecord(client); FinishedStageRaceZone(client); } else if (g_iClientStage[client] == ((l_iZoneIndex / 2 ) -1) && !g_bMessage[client][g_iClientStage[client]]) { MYSQLCheckRecord(client); FinishedStageRaceZone(client); } } /* * COMMENTS * forward checks if isValidClient * * individual seconds and minutes are zero if the client never left a zone with the name ZONE_PREFIX_START * * assuming each zone indexes one up RetrieveZoneIndex should match well since there has to be some kind * of structure for this, minimum is 2 for RetrieveZoneIndex so -1 works * * the else return statement means for example ZONE_PREFIX_START_1 but reached ZONE_PREFIX_RACE_3 * or ZONE_PREFIX_START_2 but ZONE_PREFIX_RACE_1 where it would need to be 3 * * l_iZoneIndex / 2 is stage zones, the only possible entries here are 2, 4, 6 etc etc */ } //---------------------------------------------------------------------------------------------------- // 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)) { g_fSecondsIndividual[client] = g_fRoundSeconds; g_fMinutesIndividual[client] = g_fRoundMinutes; /** * /2 is to ensure 1 + 1 / 2 = 1, 3 + 1 / 2 = 2, 5 + 1 / 2 = 3 * - 1 for starting index at 0 and +1 for int parameter stage when inserting time to row since they start as stage 1 not stage 0 */ g_iClientStage[client] = ((RetrieveZoneIndex(zone) + 1) / 2) - 1; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void unloze_zoneCreated() { startTimer(); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void CheckIfSpecialRoundZones(char[] resultstart, char[] resultend) { Format(g_cSpecialMapStart, sizeof(g_cSpecialMapStart), resultstart); Format(g_cSpecialMapEnd, sizeof(g_cSpecialMapEnd), resultend); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void CheckifAntiZones(int client, bool reset) { if (reset) { //adds 30 mins and 30 seconds to a client because thats simple and very effective g_fSecondsIndividual[client] = 30.0; g_fMinutesIndividual[client] = 30.0; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int RetrieveZoneIndex(char[] zone) { //if you leave zone_2 you want the corresponding racezone to be zone_3 int i = strlen(zone) - 1; char l_sZone[g_dIndex]; Format(l_sZone, sizeof(l_sZone), zone); while (IsCharNumeric(l_sZone[i])) i--; i++; strcopy(l_sZone, sizeof(l_sZone), l_sZone[i]); return StringToInt(l_sZone[i]); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void FinishedStageRaceZone(int client) { /* PrintToChatAll("g_iClientStage[client]: %i", g_iClientStage[client]); PrintToChatAll("g_iRecordMinutes[client][g_iClientStage[client]]: %i", g_iRecordMinutes[client][g_iClientStage[client]]); PrintToChatAll("g_fRecordSeconds[client][g_iClientStage[client]]: %f", g_fRecordSeconds[client][g_iClientStage[client]]); */ int l_iZoneCount = unloze_zoneCount(); float l_fCalculateMins; float l_fCalculateSecs; if (g_iRecordMinutes[client][g_iClientStage[client]] > 0 || g_fRecordSeconds[client][g_iClientStage[client]] > 0.0) CPrintToChat(client, "Your record: 0%i:%.1f \nCommand: !toptime !mytime !stages", g_iRecordMinutes[client][g_iClientStage[client]], g_fRecordSeconds[client][g_iClientStage[client]]); else { if (l_iZoneCount < 2) sendMYSQL(client, g_fRoundMinutes, g_fRoundSeconds, 0, 0.0, g_iClientStage[client]); else { l_fCalculateMins = CalculateValues(client, 0); l_fCalculateSecs = CalculateValues(client, 1); sendMYSQL(client, l_fCalculateMins, l_fCalculateSecs, 0, 0.0, g_iClientStage[client]); } CPrintToChat(client, "Updated timer"); } if (l_iZoneCount < 2) { //no start zone, we use round time CPrintToChat(client, "{green}[UNLOZE] Client: %N Time: 0%i:%.1f", client, RoundToFloor(g_fRoundMinutes), g_fRoundSeconds); if ((g_fRoundMinutes < g_iRecordMinutes[client][g_iClientStage[client]]) || (g_fRoundMinutes == g_iRecordMinutes[client][g_iClientStage[client]] && g_fRoundSeconds < g_fRecordSeconds[client][g_iClientStage[client]])) { sendMYSQL(client, g_fRoundMinutes, g_fRoundSeconds, g_iRecordMinutes[client][g_iClientStage[client]], g_fRecordSeconds[client][g_iClientStage[client]], g_iClientStage[client]); CPrintToChat(client, "Updated timer"); } } else { //uses start zone, we use time when leaving start zone l_fCalculateMins = CalculateValues(client, 0); l_fCalculateSecs = CalculateValues(client, 1); //tricking ppl !hehe CPrintToChat(client, "{green}[UNLOZE] Stage: %i", g_iClientStage[client] + 1); CPrintToChat(client, "{green}[UNLOZE] Client: %N Time: 0%i:%.1f", client, RoundToFloor(l_fCalculateMins), l_fCalculateSecs); if ((RoundToFloor(l_fCalculateMins) < g_iRecordMinutes[client][g_iClientStage[client]]) || (RoundToFloor(l_fCalculateMins) == g_iRecordMinutes[client][g_iClientStage[client]] && l_fCalculateSecs < g_fRecordSeconds[client][g_iClientStage[client]])) { sendMYSQL(client, l_fCalculateMins, l_fCalculateSecs, g_iRecordMinutes[client][g_iClientStage[client]], g_fRecordSeconds[client][g_iClientStage[client]], g_iClientStage[client]); CPrintToChat(client, "Updated timer"); } } //matching the message MYSQLCheckRecord(client); g_bMessage[client][g_iClientStage[client]] = true; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public float CalculateValues(int client, int state) { // 2:24 enter with roundtime 5:29 = 3:05 // 3:01 enter with roundtime 3:59 = 58 sec //example roundtime is 5 mins 40 seconds, client entered at 4 mins and 50 seconds, so 50 sec race float l_fRoundMinutes = g_fRoundMinutes; float l_fRoundMinutesIndividual = g_fMinutesIndividual[client]; float l_fRoundSeconds = g_fRoundSeconds; float l_fRoundSecondsIndividual = g_fSecondsIndividual[client]; float l_fSecAdd; if (l_fRoundMinutesIndividual > l_fRoundMinutes) return 0.0; if (!state) { l_fRoundMinutes = l_fRoundMinutes - l_fRoundMinutesIndividual; if (l_fRoundSeconds < l_fRoundSecondsIndividual) l_fRoundMinutes--; return l_fRoundMinutes; } else { if (l_fRoundSeconds < l_fRoundSecondsIndividual) { while (l_fRoundSecondsIndividual < 60) { l_fRoundSecondsIndividual++; l_fSecAdd++; } return l_fSecAdd + l_fRoundSeconds; } else return l_fRoundSeconds - l_fRoundSecondsIndividual; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void MYSQLCheckMapEntry() { int l_iRaceCount; int l_iZoneCount = unloze_zoneCount(); char sQuery[g_dLength]; char l_cZoneIndexName[g_dIndex][g_dLength]; if (l_iZoneCount < 2) { Format(sQuery, sizeof(sQuery), "SELECT `%s` FROM `zetimer_table` LIMIT 1", g_cMapname); SQL_TQuery(g_dDatabase, TqueryThreadCallback, sQuery); } else for (int i = 0; i <= l_iZoneCount; i++) { if (IsCorrectZone(i, l_cZoneIndexName[i][g_dLength -1], "ZONE_PREFIX_RACE")) { l_iRaceCount++; Format(sQuery, sizeof(sQuery), "SELECT `%sS%i` FROM `zetimer_table` LIMIT 1", g_cMapname, l_iRaceCount); SQL_TQuery(g_dDatabase, TqueryThreadCallback, sQuery); } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void TqueryThreadRecentCheckStageSteamID(Handle owner, Handle rs, const char[] error, any data) { int client = 0; if (!(client = GetClientOfUserId(data))) return; g_bRecentTimes[client] = false; if (SQL_GetRowCount(rs) > 0 && SQL_FetchRow(rs)) { g_bRecentTimes[client] = true; g_iTableCountID = SQL_FetchInt(rs, 0); } } //---------------------------------------------------------------------------------------------------- // Purpose: we define the last 500 updated times as "recently", this indicates that recent times will display 500 and not more //--------------------------------------------------------------------------------------------------- public void TqueryThreadRecentTimesCount(Handle owner, Handle rs, const char[] error, any data) { if (SQL_GetRowCount(rs) > 0 && SQL_FetchRow(rs)) { int l_isize = SQL_GetRowCount(rs); if (l_isize >= 500) g_iTableCountID = 1; else g_iTableCountID = 0; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void TqueryThreadRecentCount(Handle owner, Handle rs, const char[] error, any data) { if (SQL_GetRowCount(rs) > 0 && SQL_FetchRow(rs)) { g_iTableCountID = SQL_FetchInt(rs, 0); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void TqueryThreadCallback(Handle owner, Handle rs, const char[] error, any data) { int l_iRaceCount; int l_iZoneCount = unloze_zoneCount(); int l_iCountFix = GetTotalRaceZones(); int client = 0; float l_fRecordTotal; char sQuery[g_dLength]; char l_cZoneIndexName[g_dIndex][g_dLength]; /* *the null check is for MYSQLCheckMapEntry and MYSQLCheckRecord to check if tables exist */ if (rs == null) { if (l_iZoneCount == 1) { Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table` ADD COLUMN `%s` DECIMAL(13,3) NOT NULL", g_cMapname); SQL_FastQuery(g_dDatabase, sQuery); } else { //this might seem repetitive but one null check adds all required coloumns for (int i = 0; i <= l_iZoneCount; i++) { if (IsCorrectZone(i, l_cZoneIndexName[i][g_dLength -1], "ZONE_PREFIX_RACE")) { l_iRaceCount++; Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table` ADD COLUMN `%sS%i` DECIMAL(13,3) NOT NULL", g_cMapname, l_iRaceCount); SQL_FastQuery(g_dDatabase, sQuery); } } } return; } if (!(client = GetClientOfUserId(data))) return; if (l_iCountFix < g_iRaceCount[client]) { g_iRaceCount[client] = 0; } if (SQL_GetRowCount(rs) > 0 && SQL_FetchRow(rs)) { l_fRecordTotal = SQL_FetchFloat(rs, 0); g_iRecordMinutes[client][g_iRaceCount[client]] = (RoundToFloor(l_fRecordTotal)); g_fRecordSeconds[client][g_iRaceCount[client]] = (l_fRecordTotal - g_iRecordMinutes[client][g_iRaceCount[client]]) * 100; } else { g_iRecordMinutes[client][g_iRaceCount[client]] = 0; g_fRecordSeconds[client][g_iRaceCount[client]] = 0.0; } g_iRaceCount[client]++; } //---------------------------------------------------------------------------------------------------- // Purpose: TODO implement if needed //---------------------------------------------------------------------------------------------------- public int GetTotalRaceZones() { int l_iZoneCount = unloze_zoneCount(); char l_cIndexName[g_dLength]; int l_iCountRace; for (int i = 0; i < l_iZoneCount; i++) { ZoneNameBasedOnIndex(i, l_cIndexName[i]); if (StrContains(l_cIndexName[i], "ZONE_PREFIX_RACE") > -1) l_iCountRace++; } return l_iCountRace; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void sendMYSQL(int client, float minutes, float seconds, int oldminutes, float oldseconds, int stage) { int l_iZoneCount = unloze_zoneCount(); float l_fPlayerTime; float l_fPlayerTimeOld; char sSID[g_dIndex]; char l_cClientName[g_dIndex]; char l_cStage[90]; char sQuery[g_dLength]; char sName[MAX_NAME_LENGTH]; stage++; GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID)); GetClientName(client, sName, sizeof(sName)); int size2 = 2 * strlen(sName) + 1; char[] sEscapedName = new char[size2 + 1]; SQL_EscapeString(g_dDatabase, sName, sEscapedName, size2 + 1); Format(l_cClientName, sizeof(l_cClientName), sEscapedName); //STEAM_ID_STOP_IGNORING_RETVALS might be considered exploit? if (StrEqual(sSID, "STEAM_ID_STOP_IGNORING_RETVALS")) return; l_fPlayerTime = minutes; l_fPlayerTime = l_fPlayerTime + (seconds / 100); if (oldminutes != 0 || oldseconds != 0.0) { l_fPlayerTimeOld += oldminutes; l_fPlayerTimeOld = l_fPlayerTimeOld + (oldseconds / 100); if (l_iZoneCount > 1) Format(l_cStage, sizeof(l_cStage), "%sS%i", g_cMapname, stage); else Format(l_cStage, sizeof(l_cStage), "%s", g_cMapname); MYSQLSafeTime(client, l_cStage, l_fPlayerTimeOld); } if (l_iZoneCount < 2) Format(sQuery, sizeof(sQuery), "INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%s`) VALUES ('%s', '%s', '%f') ON DUPLICATE KEY UPDATE `name` = '%s', `%s` = '%f'", g_cMapname, sSID, l_cClientName, l_fPlayerTime, l_cClientName, g_cMapname, l_fPlayerTime); else Format(sQuery, sizeof(sQuery), "INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%sS%i`) VALUES ('%s', '%s', '%f') ON DUPLICATE KEY UPDATE `name` = '%s', `%sS%i` = '%f'", g_cMapname, stage, sSID, l_cClientName, l_fPlayerTime, l_cClientName, g_cMapname, stage, l_fPlayerTime); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void SQL_StartConnection() { char error[g_dLength]; if (SQL_CheckConfig("racetimercss")) g_dDatabase = SQL_Connect("racetimercss", true, error, sizeof(error)); if (g_dDatabase == null) { CPrintToChatAll("{green}[UNLOZE] {white}Error! Could not connect to MYSQL-DB!"); } //create tables char sQuery[g_dLength]; Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `zetimer_table` (`steam_auth` VARCHAR(254) NOT NULL, `name` VARCHAR(254) NOT NULL, PRIMARY KEY (`steam_auth`))"); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `unloze_racetimer_css`.`recenttimes_table` (`ID` INT NOT NULL AUTO_INCREMENT, `Steam_auth` VARCHAR(45) NOT NULL, `Stage` VARCHAR(90) NOT NULL, `Oldtime` VARCHAR(45) NOT NULL, PRIMARY KEY (`ID`)) ENGINE = InnoDB;"); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `unloze_racetimer_css`.`recenttimes_tableCount` (`ID` INT NOT NULL, PRIMARY KEY (`ID`)) ENGINE = InnoDB;"); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void MYSQLSafeTime(int client, char[] stage, float oldtime) { char sSID[g_dIndex]; char sQuery[g_dLength]; GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID)); //maybe %f is questionable here //check if same steam ID on same Stage is present Format(sQuery, sizeof(sQuery), "SELECT * FROM `recenttimes_table` WHERE `Steam_auth` = '%s' AND `Stage` = '%s'", sSID, stage); SQL_TQuery(g_dDatabase, TqueryThreadRecentCheckStageSteamID, sQuery, client); if (g_bRecentTimes[client]) { Format(sQuery, sizeof(sQuery), "UPDATE `recenttimes_table` SET `Steam_auth` = '%s', `Stage` = '%s', `Oldtime` = '%f' WHERE `ID`='%i'", sSID, stage, oldtime, g_iTableCountID); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); } else { Format(sQuery, sizeof(sQuery), "SELECT * FROM `recenttimes_table`"); SQL_TQuery(g_dDatabase, TqueryThreadRecentTimesCount, sQuery); if (!g_iTableCountID) { Format(sQuery, sizeof(sQuery), "INSERT INTO `recenttimes_table` (`ID`,`Steam_auth`,`Stage`,`Oldtime`) VALUES (NULL,'%s','%s','%f')", sSID, stage, oldtime); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); } else { Format(sQuery, sizeof(sQuery), "SELECT * FROM `recenttimes_tableCount`"); SQL_TQuery(g_dDatabase, TqueryThreadRecentCount, sQuery); if (g_iTableCountID <= 500) { Format(sQuery, sizeof(sQuery), "UPDATE `recenttimes_tableCount` SET `ID` = '%i'", g_iTableCountID + 1); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); } else { Format(sQuery, sizeof(sQuery), "UPDATE `recenttimes_tableCount` SET `ID` = '1'"); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); g_iTableCountID = 1; } Format(sQuery, sizeof(sQuery), "UPDATE `recenttimes_table` SET `Steam_auth` = '%s', `Stage` = '%s', `Oldtime` = '%f' WHERE `ID`='%i'", sSID, stage, oldtime, g_iTableCountID); SQL_TQuery(g_dDatabase, DummyCallbackSimple, sQuery); } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void MYSQLCheckRecord(int client) { g_iRaceCount[client] = 0; int l_iZoneCount = unloze_zoneCount(); int l_iRaceCount; char sSID[g_dIndex]; char sQuery[g_dLength]; char l_cZoneIndexName[g_dIndex][g_dLength]; GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID)); if (l_iZoneCount < 2) { Format(sQuery, sizeof(sQuery), "SELECT `%s` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, sSID); SQL_TQuery(g_dDatabase, TqueryThreadCallback, sQuery, GetClientUserId(client)); } else { for (int i = 0; i <= l_iZoneCount; i++) { if (IsCorrectZone(i, l_cZoneIndexName[i][g_dLength -1], "ZONE_PREFIX_RACE")) { l_iRaceCount++; Format(sQuery, sizeof(sQuery), "SELECT `%sS%i` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, l_iRaceCount, sSID); SQL_TQuery(g_dDatabase, TqueryThreadCallback, sQuery, GetClientUserId(client)); } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void DummyCallbackSimple(Handle hOwner, Handle hChild, const char[] err, DataPack pack1) { if (hOwner == null || hChild == null) LogError("Query error. (%s)", err); MYSQLCheckMapEntry(); } //---------------------------------------------------------------------------------------------------- // 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]; if (!l_iZoneCount) { CPrintToChat(client, "[UNLOZE] Map does not support race timer"); return; } if (l_iZoneCount > 1 && !autismstate) { CheckStagesOnMap(client, 0); return; } if (l_iZoneCount < 2) Format(sQuery, sizeof(sQuery), "SELECT name, %s FROM `zetimer_table` WHERE %s > 0.000 ORDER BY %s ASC LIMIT 10", g_cMapname, g_cMapname, g_cMapname); else Format(sQuery, sizeof(sQuery), "SELECT name, `%sS%i` FROM `zetimer_table` WHERE `%sS%i` > 0.000 ORDER BY `%sS%i` ASC LIMIT 10", g_cMapname, index, g_cMapname, index, g_cMapname, index); SQL_TQuery(g_dDatabase, SQL_SelectTop_Callback, sQuery, GetClientUserId(client)); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void SQL_SelectTop_Callback(Handle db, Handle results, const char[] error, any data) { int client = GetClientOfUserId(data); int l_iMinutes; int l_iPosition; float l_fRecord; float l_iSeconds; //Player Name char[] g_cPlayerName = new char[MAX_NAME_LENGTH]; char g_cContent[g_dLength]; if (client == 0) { return; } Menu menu = new Menu(MenuHandler1); menu.SetTitle("Maptimer: %s", g_cMapname); while (SQL_GetRowCount(results) > 0 && SQL_FetchRow(results)) { l_iPosition++; SQL_FetchString(results, 0, g_cPlayerName, MAX_NAME_LENGTH); l_fRecord = SQL_FetchFloat(results, 1); l_iMinutes = RoundToFloor(l_fRecord); l_iSeconds = (l_fRecord - l_iMinutes) * 100; Format(g_cContent, sizeof(g_cContent), "#%i: Time: 0%i:%.1f - %s", l_iPosition, l_iMinutes, l_iSeconds, g_cPlayerName); menu.AddItem("-1", g_cContent, ITEMDRAW_DISABLED); } if (!l_iPosition) { menu.AddItem("-1", "No results. Commands: !toptime !stages", ITEMDRAW_DISABLED); } menu.ExitButton = true; menu.Display(client, 0); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2) { if (action == MenuAction_End) { delete menu; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action cmd_timerCheckStage(int client, int args) { CheckStagesOnMap(client, 0); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action cmd_threadtest(int client, int args) { g_iRaceCount[client] = 0; int l_iRaceCount; int l_iZoneCount = unloze_zoneCount(); char sQuery[g_dLength]; char l_cZoneIndexName[g_dIndex][g_dLength]; char sSID[g_dIndex]; GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID)); for (int i = 0; i <= l_iZoneCount; i++) { if (IsCorrectZone(i, l_cZoneIndexName[i][g_dLength -1], "ZONE_PREFIX_RACE")) { l_iRaceCount++; Format(sQuery, sizeof(sQuery), "SELECT `%sS%i` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, l_iRaceCount, sSID); SQL_TQuery(g_dDatabase, TqueryThreadCallback, sQuery, GetClientUserId(client)); } } 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) { Format(l_cMenuContent, sizeof(l_cMenuContent), "Stage: %i", l_iCount); StageMenu.AddItem("", l_cMenuContent); } else for (int i = 0; i <= l_iZoneCount; i++) { if (IsCorrectZone(i, l_cZoneIndexName[i][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 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) { CPrintToChat(client, "[UNLOZE] Map does not support race timer"); return; } if (l_iZoneCount < 2) { Format(l_cQuery, sizeof(l_cQuery), "SELECT name, `%s` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, l_cSID); SQL_TQuery(g_dDatabase, TqueryCheckSelf, l_cQuery, GetClientUserId(client)); } else { CheckStagesOnMap(client, 1); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void CheckStageSelf(int client, int selection) { char l_cQuery[g_dLength]; char l_cSID[g_dIndex]; GetClientAuthId(client, AuthId_Steam2, l_cSID, sizeof(l_cSID)); Format(l_cQuery, sizeof(l_cQuery), "SELECT name, `%sS%i` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, selection, l_cSID); SQL_TQuery(g_dDatabase, TqueryCheckSelf, l_cQuery, GetClientUserId(client)); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void TqueryCheckSelf(Handle db, Handle rs, const char[] error, any data) { int l_iMinutes; float l_fRecord; float l_iSeconds; char l_cMessageContent[g_dLength]; char[] l_cPlayerName = new char[MAX_NAME_LENGTH]; int client; if ((client = GetClientOfUserId(data)) == 0) return; if (SQL_GetRowCount(rs) > 0 && SQL_FetchRow(rs)) { SQL_FetchString(rs, 0, l_cPlayerName, MAX_NAME_LENGTH); l_fRecord = SQL_FetchFloat(rs, 1); if (l_fRecord == 0.000) { CPrintToChat(client, "You have no time yet!"); return; } l_iMinutes = RoundToFloor(l_fRecord); l_iSeconds = (l_fRecord - l_iMinutes) * 100; Format(l_cMessageContent, sizeof(l_cMessageContent), "%i:%.1f - %s", l_iMinutes, l_iSeconds, l_cPlayerName); CPrintToChat(client, "Your best time: 0%s", l_cMessageContent); } else CPrintToChat(client, "You have no time yet!"); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool IsValidClient(int client) { if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) { return true; } return false; }