#pragma semicolon 1 #define PLUGIN_AUTHOR "jenz" #define PLUGIN_VERSION "1.1" #include #include #include Database g_hDatabase; //check if autismbot bool is_bot_player[MAXPLAYERS + 1]; Handle g_h_time_activity = null; char g_cTimeRecords[100][128]; int g_iPlayerTimeServer[MAXPLAYERS + 1]; int g_iPlayerAFKTime; public Plugin myinfo = { name = "UNLOZE_player_time", author = PLUGIN_AUTHOR, description = "checks playtime on servers", version = PLUGIN_VERSION, url = "www.unloze.com" }; public Action time_query_activity(Handle timer, any data) { if (!g_hDatabase) { Database.Connect(SQL_OnDatabaseConnect, "unloze_playtimestats"); return Plugin_Continue; } for (int client = 1; client <= MaxClients; client++) if (IsValidClient(client) && !IsFakeClient(client) && IsPlayerAlive(client)) { char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); char sIP[32]; GetClientIP(client, sIP, sizeof(sIP)); char sQuery[512]; char sServer[64]; int i_port = GetConVarInt(FindConVar("hostport")); if (i_port == 27015) { Format(sServer, sizeof(sServer), "ze_time"); } else if (i_port == 27016) { Format(sServer, sizeof(sServer), "zr_time"); } else if (i_port == 27017) { Format(sServer, sizeof(sServer), "mg_time"); } else if (i_port == 27023) { Format(sServer, sizeof(sServer), "jb_time"); } else { continue; } char sName[MAX_NAME_LENGTH]; GetClientName(client, sName, sizeof(sName)); int size2 = 2 * strlen(sName) + 1; char[] sEscapedName = new char[size2 + 1]; g_hDatabase.Escape(sName, sEscapedName, size2 + 1); Format(sQuery, sizeof(sQuery), "update unloze_playtimestats.player_time set `%s` = `%s` + 10, player_name = '%s' where steam_id = '%s' and ipv4 = '%s'", sServer, sServer, sEscapedName, sAuthID, sIP); //LogError("sQuery: %s", sQuery); g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low); } return Plugin_Continue; } 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"); g_h_time_activity = CreateTimer(10.0, time_query_activity, INVALID_HANDLE, TIMER_REPEAT); ConVar cvar; HookConVarChange((cvar = CreateConVar("sm_mapchooser_afk_detect_time", "120", "Time in seconds until a player is considered as AFK and therefore excluded from player average time.")), Cvar_playerAFKTime); g_iPlayerAFKTime = cvar.IntValue; delete cvar; } public void Cvar_playerAFKTime(ConVar convar, const char[] oldValue, const char[] newValue) { g_iPlayerAFKTime = convar.IntValue; } public APLRes AskPluginLoad2(Handle myself, bool late, char [] error, int err_max) { CreateNative("GetAveragePlayerTimeOnServer", Native_GetAveragePlayerActiveTimeServer); return APLRes_Success; } public int Native_GetAveragePlayerActiveTimeServer(Handle plugin, int numParams) { int total_hours = 0; int total_players = 0; for (int i = 0; i < MaxClients; i++) { if (IsValidClient(i) && !IsFakeClient(i) && !IsClientSourceTV(i) && !is_bot_player[i] && PM_IsPlayerSteam(i) && GetClientIdleTime(i) < g_iPlayerAFKTime) { total_hours += g_iPlayerTimeServer[i]; total_players++; } } if (total_hours == 0) { return 0; } return total_hours / total_players; } public void OnPluginEnd() { if (g_h_time_activity != null) delete g_h_time_activity; } public void SQL_OnDatabaseConnect(Database db, const char[] error, any data) { if(!db || strlen(error)) { LogError("Database error: %s", error); return; } g_hDatabase = db; for (int i = 1; i <= MaxClients; i++) OnClientPostAdminCheck(i); OnMapStart(); } public void OnClientPostAdminCheck(int client) { is_bot_player[client] = false; g_iPlayerTimeServer[client] = 0; if(!IsValidClient(client) || IsFakeClient(client)) return; if (!g_hDatabase) { Database.Connect(SQL_OnDatabaseConnect, "unloze_playtimestats"); return; } insert_client(client); select_client_time_server(client); char auth[50]; GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth)); if (StrEqual("[U:1:1221121532]", auth, false) || StrEqual("STEAM_0:0:610560766", auth, false)) { is_bot_player[client] = true; } if (StrEqual("[U:1:408797742]", auth, false) || StrEqual("STEAM_0:0:204398871", auth, false)) { is_bot_player[client] = true; } if (StrEqual("[U:1:1036189204]", auth, false) || StrEqual("STEAM_0:0:518094602", auth, false)) { is_bot_player[client] = true; } if (StrEqual("[U:1:120378081]", auth, false) || StrEqual("STEAM_0:1:60189040", auth, false)) { is_bot_player[client] = true; } } public void select_client_time_server(int client) { char sServer[32]; int i_port = GetConVarInt(FindConVar("hostport")); if (i_port == 27015 || i_port == 27019) { Format(sServer, sizeof(sServer), "ze_time"); } else if (i_port == 27016) { Format(sServer, sizeof(sServer), "zr_time"); } else if (i_port == 27017) { Format(sServer, sizeof(sServer), "mg_time"); } else if (i_port == 27023) { Format(sServer, sizeof(sServer), "jb_time"); } else { return; } char sQuery[512]; char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); Format(sQuery, sizeof(sQuery), "select sum(%s) as %s_total from unloze_playtimestats.player_time pt where pt.steam_id = '%s' GROUP BY steam_id order by %s_total desc", sServer, sServer, sAuthID, sServer); g_hDatabase.Query(SQL_OnQueryCompletedTimeServer, sQuery, GetClientSerial(client)); } public void SQL_OnQueryCompletedTimeServer(Database db, DBResultSet results, const char[] error, int iSerial) { if (!db || strlen(error)) { LogError("Query error 3: %s", error); } int client; if ((client = GetClientFromSerial(iSerial)) == 0) return; int iTime_Server; while (results.RowCount && results.FetchRow()) { iTime_Server += results.FetchInt(0); } delete results; int iHours_Server = (iTime_Server / 60) / 60; g_iPlayerTimeServer[client] = iHours_Server; } public void OnClientDisconnect(int client) { is_bot_player[client] = false; g_iPlayerTimeServer[client] = 0; } public void insert_client(int client) { char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); char sName[MAX_NAME_LENGTH]; GetClientName(client, sName, sizeof(sName)); int size2 = 2 * strlen(sName) + 1; char[] sEscapedName = new char[size2 + 1]; g_hDatabase.Escape(sName, sEscapedName, size2 + 1); char sIP[32]; GetClientIP(client, sIP, sizeof(sIP)); char sQuery[512]; Format(sQuery, sizeof(sQuery), "INSERT INTO `player_time` (`steam_id`, `ipv4`, `player_name`, `ze_time`, `mg_time`, `zr_time`, `jb_time`) VALUES ('%s', '%s', '%s', 0, 0, 0, 0) ON DUPLICATE KEY UPDATE `player_name` = '%s'", sAuthID, sIP, sEscapedName, sEscapedName); g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low); } public void SQL_FinishedQuery(Database db, DBResultSet results, const char[] error, any data) { if (!db || strlen(error)) { LogError("Query error 3: %s", error); } delete results; } stock bool IsValidClient(int client) { if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) return true; return false; } public void OnMapStart() { if (!g_hDatabase) { Database.Connect(SQL_OnDatabaseConnect, "unloze_playtimestats"); return; } char sQuery[512]; char sServer[32]; int i_port = GetConVarInt(FindConVar("hostport")); if (i_port == 27015 || i_port == 27019) { Format(sServer, sizeof(sServer), "ze_time"); } else if (i_port == 27016) { Format(sServer, sizeof(sServer), "zr_time"); } else if (i_port == 27017) { Format(sServer, sizeof(sServer), "mg_time"); } else if (i_port == 27023) { Format(sServer, sizeof(sServer), "jb_time"); } else { return; } Format(sQuery, sizeof(sQuery), "select player_name, sum(%s) as %s_total from unloze_playtimestats.player_time GROUP BY steam_id order by %s_total desc limit 100", sServer, sServer, sServer); g_hDatabase.Query(SQL_OnQueryCompletedTopTime, sQuery); } public Action Command_TopTime(int client, int args) { char sTitle[64]; char sServer[32]; int i_port = GetConVarInt(FindConVar("hostport")); if (i_port == 27015 || i_port == 27019) { Format(sServer, sizeof(sServer), "ZE"); } else if (i_port == 27016) { Format(sServer, sizeof(sServer), "ZR"); } else if (i_port == 27017) { Format(sServer, sizeof(sServer), "MG"); } else if (i_port == 27023) { Format(sServer, sizeof(sServer), "JB"); } Format(sTitle, sizeof(sTitle), "[UNLOZE Playtime] Top 100 Record Holders for %s:", sServer); Menu menu = new Menu(MenuHandler1); menu.SetTitle(sTitle); for (int i = 0; i < sizeof(g_cTimeRecords); i++) { menu.AddItem("-1", g_cTimeRecords[i], ITEMDRAW_DISABLED); } menu.ExitButton = true; menu.Display(client, 0); } public Action Command_Time(int client, int args) { if (!g_hDatabase) { Database.Connect(SQL_OnDatabaseConnect, "unloze_playtimestats"); return Plugin_Handled; } char sQuery[512]; char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); Format(sQuery, sizeof(sQuery), "select ze_time, mg_time, zr_time, jb_time from unloze_playtimestats.player_time pt where pt.steam_id = '%s'", sAuthID); g_hDatabase.Query(SQL_OnQueryCompletedTime, sQuery, GetClientSerial(client)); return Plugin_Handled; } public void SQL_OnQueryCompletedTopTime(Database db, DBResultSet results, const char[] error, int iSerial) { if (!db || strlen(error)) { LogError("Query error 3: %s", error); } int iTime; char sName[MAX_NAME_LENGTH]; int counter = 0; while (results.RowCount && results.FetchRow()) { char sBuffer[256]; results.FetchString(0, sName, sizeof(sName)); iTime = results.FetchInt(1); int iHours = (iTime / 60) / 60; Format(sBuffer, sizeof(sBuffer), "%i %s %d Hours", counter + 1, sName, iHours); Format(g_cTimeRecords[counter], sizeof(g_cTimeRecords[]), sBuffer); counter++; } delete results; } public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2) { switch(action) { case MenuAction_End: { delete menu; } } return 0; } public void SQL_OnQueryCompletedTime(Database db, DBResultSet results, const char[] error, int iSerial) { if (!db || strlen(error)) { LogError("Query error 3: %s", error); } int client; if ((client = GetClientFromSerial(iSerial)) == 0) return; int iTime_ze; int iTime_mg; int iTime_zr; int iTime_jb; while (results.RowCount && results.FetchRow()) { iTime_ze += results.FetchInt(0); iTime_mg += results.FetchInt(1); iTime_zr += results.FetchInt(2); iTime_jb += results.FetchInt(3); } delete results; int iHours_ze = (iTime_ze / 60) / 60; int iMinutes_ze = (iTime_ze / 60) % 60; int iSeconds_ze = (iTime_ze % 60); int iHours_mg = (iTime_mg / 60) / 60; int iMinutes_mg = (iTime_mg / 60) % 60; int iSeconds_mg = (iTime_mg % 60); int iHours_zr = (iTime_zr / 60) / 60; int iMinutes_zr = (iTime_zr / 60) % 60; int iSeconds_zr = (iTime_zr % 60); int iHours_jb = (iTime_jb / 60) / 60; int iMinutes_jb = (iTime_jb / 60) % 60; int iSeconds_jb = (iTime_jb % 60); char sTime_ze[64]; char sTime_mg[64]; char sTime_zr[64]; char sTime_jb[64]; char sTitle[64]; Format(sTitle, sizeof(sTitle), "[UNLOZE Playtime] Player %N:", client); Format(sTime_ze, sizeof(sTime_ze), "Zombie Escape: %d Hours %d Minutes %d Seconds", iHours_ze, iMinutes_ze, iSeconds_ze); Format(sTime_mg, sizeof(sTime_mg), "MiniGame: %d Hours %d Minutes %d Seconds", iHours_mg, iMinutes_mg, iSeconds_mg); Format(sTime_zr, sizeof(sTime_zr), "Zombie Riot: %d Hours %d Minutes %d Seconds", iHours_zr, iMinutes_zr, iSeconds_zr); Format(sTime_jb, sizeof(sTime_jb), "Jail Break: %d Hours %d Minutes %d Seconds", iHours_jb, iMinutes_jb, iSeconds_jb); Panel mSayPanel = new Panel(GetMenuStyleHandle(MenuStyle_Radio)); mSayPanel.SetTitle(sTitle); mSayPanel.DrawItem("", ITEMDRAW_SPACER); mSayPanel.DrawText(sTime_ze); mSayPanel.DrawItem("", ITEMDRAW_SPACER); mSayPanel.DrawText(sTime_mg); mSayPanel.DrawItem("", ITEMDRAW_SPACER); mSayPanel.DrawText(sTime_zr); mSayPanel.DrawItem("", ITEMDRAW_SPACER); mSayPanel.DrawText(sTime_jb); mSayPanel.DrawItem("", ITEMDRAW_SPACER); mSayPanel.DrawItem("1. Got it!", ITEMDRAW_RAWLINE); mSayPanel.SetKeys(1023); mSayPanel.Send(client, Handler_Menu, 0); delete mSayPanel; } public int Handler_Menu(Menu menu, MenuAction action, int param1, int param2) { switch(action) { case MenuAction_Select, MenuAction_Cancel: delete menu; } }