public void EstablishConnection() { if (SQL_CheckConfig("ctimer")) Database.Connect(ConnectionCallback, "ctimer"); else SetFailState("'ctimer' not found in 'sourcemod/configs/databases.cfg'"); } public void ConnectionCallback(Database db, const char[] error, any data) { if (db == null) { SetFailState("Failed to connect to the database, will attempt to reconnect on map change"); return; } g_hDatabase = db; LoadMapInfo(); } public void GetPlayerInfo(client) { int steamid = GetTimerSteamId(client); char query[512], username[65], ip[16]; GetClientName(client, username, sizeof(username)); g_hDatabase.Escape(username, username, sizeof(username)); GetClientIP(client, ip, sizeof(ip)); Format(query, sizeof(query), "INSERT INTO ctimer_users (userid, name, ip, lastconnected) values ('%i', '%s', INET_ATON('%s'), CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE name = VALUES(name), ip = VALUES(ip), lastconnected = CURRENT_TIMESTAMP;", steamid, username, ip); g_hDatabase.Query(SQL_InsertUser, query, DBPrio_High); if (g_iMapID == -1) { LogError("Error, map ID is invalid, can't load players time %N<%i>", client, client); return; } int userid = GetClientUserId(client); Format(query, sizeof(query), "SELECT time FROM ctimer_times WHERE mapid = %i AND userid = %i;", g_iMapID, GetTimerSteamId(client)); g_hDatabase.Query(SQL_GetUserTime, query, userid); } public void SQL_InsertUser(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on inserting user: %s", error); return; } } public void SQL_GetUserTime(Database db, DBResultSet results, const char[] error, int userid) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on getting user time: %s", error); return; } int client = GetClientOfUserId(userid); if (!isValidClient(client)) return; if (results.RowCount == 0) { g_fMapTime[client] = 0.0; return; } if (results.RowCount > 1) { LogError("Unexpected amount of rows: %i", results.RowCount); return; } results.FetchRow(); g_fMapTime[client] = results.FetchFloat(0); } public void LoadMapInfo() { char query[512]; Format(query, sizeof(query), "INSERT INTO ctimer_maps (mapname, lastplayed) values ('%s', CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE lastplayed = CURRENT_TIMESTAMP", g_sMapName); g_hDatabase.Query(SQL_InsertMap, query, DBPrio_High); ///Insert map or update lastplayed Format(query, sizeof(query), "SELECT mapid, tier, enabled FROM ctimer_maps WHERE mapname = '%s'", g_sMapName); g_hDatabase.Query(SQL_GetMapInfo, query); } public void SQL_InsertMap(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on inserting map: %s", error); return; } } public void SQL_GetMapInfo(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on inserting map: %s", error); return; } if (results.RowCount == 0) { LogError("Map not found"); return; } if (results.RowCount > 1) { LogError("Unexpected amount of rows: %i", results.RowCount); return; } results.FetchRow(); g_iMapID = results.FetchInt(0); g_iTier = results.FetchInt(1); g_bActive = view_as(results.FetchInt(2)); LoadZones(); GetWRInfo(); if (g_bLateLoad) { for (int i = 1; i <= MaxClients; i++) { if (IsClientConnected(i) && IsClientInGame(i)) { OnClientPostAdminCheck(i); } } } } public void GetWRInfo() { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512]; Format(query, sizeof(query), "SELECT u.name , wr.time FROM ctimer_users u, ctimer_times wr WHERE u.userid = wr.userid AND wr.mapid = %i AND u.userid = getWrUserId(%i);", g_iMapID, g_iMapID); g_hDatabase.Query(SQL_GetWRInfo, query); } public void SQL_GetWRInfo(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on getting map WR info: %s", error); return; } if (results.RowCount == 0) { g_fWrTime = 0.0; return; } if (results.RowCount > 2) { LogError("Unexpected amount of rows: %i", results.RowCount); return; } results.FetchRow(); results.FetchString(0, g_sWrHolder, sizeof(g_sWrHolder)); g_fWrTime = results.FetchFloat(1); } public void SaveZones(int client) { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512], startcord[42], endcord[42]; for (int i = 0; i <= 1; i++) { VectorToString(startcord, sizeof(startcord), g_fStartOrigins[i]); VectorToString(endcord, sizeof(endcord), g_fEndOrigins[i]); Format(query, sizeof(query), "INSERT INTO ctimer_zones(mapid, zonetype, startcord, endcord) VALUES (%i, %i, '%s', '%s') ON DUPLICATE KEY UPDATE startcord = values(startcord), endcord = values(endcord)", g_iMapID, i, startcord, endcord); g_hDatabase.Query(SQL_SaveZones, query); } PrintToChat(client, "Zones Saved"); } public void SQL_SaveZones(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on saving zones: %s", error); return; } } public void LoadZones() { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512]; Format(query, sizeof(query), "SELECT zonetype, startcord, endcord from ctimer_zones where mapid = %i ORDER BY zonetype", g_iMapID); g_hDatabase.Query(SQL_LoadZones, query); } public void SQL_LoadZones(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on inserting map: %s", error); return; } if (results.RowCount == 0) { return; } if (results.RowCount > 2) { LogError("Unexpected amount of rows: %i", results.RowCount); return; } int zonetype; char startcord[42], endcord[42]; float vec[3]; while (results.FetchRow()) { zonetype = results.FetchInt(0); results.FetchString(1, startcord, sizeof(startcord)); results.FetchString(2, endcord, sizeof(endcord)); StringToVector(vec, startcord); g_fStartOrigins[zonetype] = vec; StringToVector(vec, endcord); g_fEndOrigins[zonetype] = vec; CreateTrigger(zonetype); //CreateTimer(1.0, Timer_CreateTrigger, zonetype); } //CS_TerminateRound(0.0, CSRoundEnd_Draw, true); } public void SetMapTier(int tier) { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512]; Format(query, sizeof(query), "UPDATE ctimer_maps SET tier = %i WHERE mapname = '%s'", tier, g_sMapName); g_hDatabase.Query(SQL_SetMapTier, query); } public void SQL_SetMapTier(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on setting map tier: %s", error); return; } } public void SetMapState(int state) { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512]; Format(query, sizeof(query), "UPDATE ctimer_maps SET enabled = %i WHERE mapname = '%s'", state, g_sMapName); g_hDatabase.Query(SQL_SetMapState, query); } public void SQL_SetMapState(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on setting map active state: %s", error); return; } } public void UpdateTime(int client) { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512]; int userid = GetClientUserId(client); Format(query, sizeof(query), "SELECT updateTime(%i, %i, %f), getTimeRank(%i, %i), getTimeComps(%i);", g_iMapID, GetTimerSteamId(client), g_fMapTime[client], g_iMapID, GetTimerSteamId(client), g_iMapID); g_hDatabase.Query(SQL_UpdateTime, query, userid); } public void SQL_UpdateTime(Database db, DBResultSet results, const char[] error, int userid) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on updating time: %s", error); return; } int client = GetClientOfUserId(userid); if (!isValidClient(client)) return; results.FetchRow(); int rank = results.FetchInt(1); int total = results.FetchInt(2); ProcessRankMessage(client, rank, total); } public void AddCompletion(int client) { if (g_iMapID == -1) { LogError("Error, map ID is invalid"); return; } char query[512]; Format(query, sizeof(query), "UPDATE ctimer_times SET timescompleted = timescompleted + 1 where mapid = %i AND userid = %i", g_iMapID, GetTimerSteamId(client)); g_hDatabase.Query(SQL_AddCompletion, query); } public void SQL_AddCompletion(Database db, DBResultSet results, const char[] error, any data) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } if (results == null) { LogError("Error on setting map active state: %s", error); return; } } public void RequestTop(int userid, char[] mapname, int limit) { Transaction transaction = new Transaction(); char query[512]; Format(query, sizeof(query), "SELECT mapname FROM ctimer_maps WHERE enabled = 1 AND mapname LIKE '%%%s%%' ORDER BY mapname LIMIT 1", mapname); transaction.AddQuery(query); Format(query, sizeof(query), "SELECT u.name , times.time, times.timescompleted FROM ctimer_users u, ctimer_times times, ctimer_maps maps WHERE u.userid = times.userid AND times.mapid = maps.mapid AND maps.mapid = (SELECT mapid FROM ctimer_maps WHERE enabled = 1 AND mapname LIKE '%%%s%%' ORDER BY mapname LIMIT 1) ORDER BY time, runid LIMIT %i;", mapname, limit); transaction.AddQuery(query); g_hDatabase.Execute(transaction, SQL_RequestTop, SQL_RequestTopError, userid); } public void SQL_RequestTopError(Database db, int userid, int numQueries, const char[] error, int failIndex, any[] queryData) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } LogError("Error on requesting top time records on query %i: %s", failIndex, error); } public void RequestWR(int userid, char[] mapname) { Transaction transaction = new Transaction(); char query[512]; Format(query, sizeof(query), "SELECT mapname FROM ctimer_maps WHERE enabled = 1 AND mapname LIKE '%%%s%%' ORDER BY mapname LIMIT 1", mapname); transaction.AddQuery(query); Format(query, sizeof(query), "SELECT name, time FROM ctimer_times times INNER JOIN ctimer_users u ON u.userid = times.userid WHERE mapid=(SELECT mapid FROM ctimer_maps WHERE enabled = 1 AND mapname LIKE '%%%s%%' ORDER BY mapname LIMIT 1) ORDER BY time, runid LIMIT 1;", mapname); transaction.AddQuery(query); g_hDatabase.Execute(transaction, SQL_RequestWR, SQL_RequestWRError, userid); } public void SQL_RequestWRError(Database db, int userid, int numQueries, const char[] error, int failIndex, any[] queryData) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } LogError("Error on requesting world record time on query %i: %s", failIndex, error); } public void SQL_RequestWR(Database db, int userid, int numQueries, DBResultSet[] results, any[] queryData) { if (db == null) { SetFailState("Lost connection to the database, will attempt to reconnect on map change"); return; } int client = GetClientOfUserId(userid); if (!isValidClient(client)) return; if (results[0].RowCount == 0) { TimerPrintToChat(client, false, "%T", "MapNotFound", LANG_SERVER); return; } char cMap[64]; results[0].FetchRow(); results[0].FetchString(0, cMap, sizeof(cMap)); if (results[1].RowCount == 0) { TimerPrintToChat(client, false, "%T", "TimesNotFound", LANG_SERVER, cMap); return; } char cTime[16], cName[64]; float fTime; results[1].FetchRow(); results[1].FetchString(0, cName, sizeof(cName)); fTime = results[1].FetchFloat(1); TimerFormat(fTime, cTime, sizeof(cTime), true, false); TimerPrintToChat(client, false, "%T", "WR", LANG_SERVER, cName, cMap, cTime); }