diff --git a/PlaytimeStats/scripting/PlaytimeStats.sp b/PlaytimeStats/scripting/PlaytimeStats.sp new file mode 100644 index 00000000..ed1ab16b --- /dev/null +++ b/PlaytimeStats/scripting/PlaytimeStats.sp @@ -0,0 +1,202 @@ +#pragma semicolon 1 + +#include +#include + +Database g_hDatabase; + +int g_iConnectionTime[MAXPLAYERS + 1]; + +public Plugin myinfo = +{ + name = "PlaytimeStats", + author = "Dogan", + description = "Retreives total playtime on multiple servers for clients", + version = "1.0.0", + url = "" +} + +public void OnPluginStart() +{ + Database.Connect(SQL_OnDatabaseConnect, "unloze_playtimestats"); + + RegConsoleCmd("sm_playtime", Command_Time, "retreives total connection time on all connected servers"); + RegConsoleCmd("sm_topplaytime", Command_TopTime, "retreives top 12 playtime highscores on all connected servers"); +} + +public Action Command_Time(int client, int args) +{ + int iAuthID = GetSteamAccountID(client); + + char sQuery[512]; + Format(sQuery, sizeof(sQuery), "SELECT time FROM playtime WHERE auth = '%d'", iAuthID); + g_hDatabase.Query(SQL_OnQueryCompletedTime, sQuery, GetClientSerial(client)); + + return Plugin_Handled; +} + +public Action Command_TopTime(int client, int args) +{ + char sQuery[255]; + Format(sQuery, sizeof(sQuery), "SELECT * from playtime order by time desc limit 12"); + g_hDatabase.Query(SQL_OnQueryCompletedTopTime, sQuery, GetClientSerial(client)); + + return Plugin_Handled; +} + +public void OnClientConnected(int client) +{ + if(IsValidClient(client)) + g_iConnectionTime[client] = GetTime(); +} + +public void OnClientDisconnect(int client) +{ + if(g_iConnectionTime[client] == 0 || !IsValidClient(client)) + return; + + int iPlayTime = GetTime() - g_iConnectionTime[client]; + + int iAuthID = GetSteamAccountID(client); + + char sQuery[512]; + Format(sQuery, sizeof(sQuery), "INSERT INTO playtime (auth,name,time) VALUES ('%d', '%N', '%d') ON DUPLICATE KEY UPDATE time=time+%d", iAuthID, client, iPlayTime, iPlayTime); + + g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_Low); +} + +public void SQL_OnDatabaseConnect(Database db, const char[] error, any data) +{ + if(!db || strlen(error)) + { + LogError("Database error: %s", error); + return; + } + + g_hDatabase = db; + + char sQuery[512]; + Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS playtime (`auth` INTEGER, `name` varchar(128), `time` INTEGER, PRIMARY KEY (`auth`))"); + + g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_Low); +} + +public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, any data) +{ + if(!db || strlen(error)) + { + LogError("Query error: %s", error); + return; + } +} + +public void SQL_OnQueryCompletedTime(Database db, DBResultSet results, const char[] error, int iSerial) +{ + int client; + if ((client = GetClientFromSerial(iSerial)) == 0) + return; + + if(!db || strlen(error)) + { + LogError("Query error: %s", error); + return; + } + + int iTime; + + if (results.RowCount && results.FetchRow()) + { + int iFieldNum; + results.FieldNameToNum("time", iFieldNum); + iTime = results.FetchInt(iFieldNum); + } + + char sTime[64]; + int iDays = (iTime/ 86400); + int iHours = (iTime / 3600) % 24; + int iMinutes = (iTime / 60) % 60; + int iSeconds = (iTime % 60); + + if (iDays) + Format(sTime, sizeof(sTime), "%d Days %d Hours %d Minutes %d Seconds", iDays, iHours, iMinutes, iSeconds); + else if (iHours) + Format(sTime, sizeof(sTime), "%d Hours %d Minutes %d Seconds", iHours, iMinutes, iSeconds); + else if (iMinutes) + Format(sTime, sizeof(sTime), "%d Minutes %d Seconds", iMinutes, iSeconds); + else + Format(sTime, sizeof(sTime), "%d Seconds", iSeconds); + + CPrintToChat(client, "{cyan}[UNLOZE Time] {white}You have played %s on Unloze Servers so far! {lightgreen}(data collected since Octobre 2019)", sTime); +} + +public void SQL_OnQueryCompletedTopTime(Database db, DBResultSet results, const char[] error, int iSerial) +{ + int client; + if ((client = GetClientFromSerial(iSerial)) == 0) + return; + + if (!db || strlen(error)) + { + LogError("Query error: %s", error); + return; + } + + char sName[12][32]; + int iTime[12]; + char sBuffer[12][128]; + + for(int i = 1; i <= 12; i++) + { + int iFieldNum; + if (!results.FetchRow()) + break; + + results.FieldNameToNum("name", iFieldNum); + results.FetchString(iFieldNum, sName[i - 1], 32); + + results.FieldNameToNum("time", iFieldNum); + iTime[i - 1] = results.FetchInt(iFieldNum); + iTime[i - 1] = (iTime[i - 1] / 60) % 60; + + Format(sBuffer[i - 1], 128, "%d. %s - %d Minutes", i, sName[i - 1], iTime[i - 1]); + } + + SendMsay(iSerial, sBuffer); +} + +public void SendMsay(int iSerial, char[][] message) +{ + int client = GetClientFromSerial(iSerial); + + Panel mSayPanel = new Panel(); + mSayPanel.SetTitle("[UNLOZE Time] Record Holders:"); + mSayPanel.DrawItem("", ITEMDRAW_SPACER); + mSayPanel.DrawText(message[0]); + mSayPanel.DrawText(message[1]); + mSayPanel.DrawText(message[2]); + mSayPanel.DrawText(message[3]); + mSayPanel.DrawText(message[4]); + mSayPanel.DrawText(message[5]); + mSayPanel.DrawText(message[6]); + mSayPanel.DrawText(message[7]); + mSayPanel.DrawText(message[8]); + mSayPanel.DrawText(message[9]); + mSayPanel.DrawText(message[10]); + mSayPanel.DrawText(message[11]); + mSayPanel.DrawText(message[12]); + mSayPanel.DrawItem("", ITEMDRAW_SPACER); + mSayPanel.DrawItem("Exit", ITEMDRAW_CONTROL); + + mSayPanel.Send(client, Handler_DoNothing, 10); + delete mSayPanel; +} + +public int Handler_DoNothing(Menu menu, MenuAction action, int param1, int param2) +{ + /* Do nothing */ +} + +stock bool IsValidClient(int client) +{ + return (client >= 1 && client <= MaxClients && !IsFakeClient(client)); +} \ No newline at end of file