2019-10-02 22:22:06 +02:00
|
|
|
#pragma semicolon 1
|
|
|
|
|
|
|
|
#include <sourcemod>
|
2019-10-19 15:08:48 +02:00
|
|
|
#include <PlayerManager>
|
2019-10-02 22:22:06 +02:00
|
|
|
|
|
|
|
Database g_hDatabase;
|
|
|
|
|
|
|
|
int g_iConnectionTime[MAXPLAYERS + 1];
|
2019-10-19 15:08:48 +02:00
|
|
|
bool g_bPlayerValid[MAXPLAYERS + 1];
|
2019-10-02 22:22:06 +02:00
|
|
|
|
2019-10-19 15:49:25 +02:00
|
|
|
ConVar g_cvServerType;
|
|
|
|
int g_iServerType;
|
|
|
|
|
2019-10-02 22:22:06 +02:00
|
|
|
public Plugin myinfo =
|
|
|
|
{
|
|
|
|
name = "PlaytimeStats",
|
|
|
|
author = "Dogan",
|
|
|
|
description = "Retreives total playtime on multiple servers for clients",
|
2019-10-19 15:49:25 +02:00
|
|
|
version = "2.0.0",
|
2019-10-02 22:22:06 +02:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2019-10-19 15:49:25 +02:00
|
|
|
public void OnAllPluginsLoaded()
|
|
|
|
{
|
|
|
|
if((g_cvServerType = FindConVar("sm_server_type")) == INVALID_HANDLE)
|
|
|
|
SetFailState("Failed to find sm_server_type cvar.");
|
|
|
|
else
|
|
|
|
g_iServerType = g_cvServerType.IntValue;
|
|
|
|
}
|
|
|
|
|
2019-10-02 22:22:06 +02:00
|
|
|
public Action Command_Time(int client, int args)
|
|
|
|
{
|
|
|
|
int iAuthID = GetSteamAccountID(client);
|
|
|
|
|
|
|
|
char sQuery[512];
|
2019-10-19 15:49:25 +02:00
|
|
|
|
|
|
|
if(g_iServerType == 1)
|
|
|
|
Format(sQuery, sizeof(sQuery), "SELECT time FROM playtimeze WHERE auth = '%d'", iAuthID);
|
|
|
|
else if(g_iServerType == 2)
|
|
|
|
Format(sQuery, sizeof(sQuery), "SELECT time FROM playtimemg WHERE auth = '%d'", iAuthID);
|
|
|
|
else if(g_iServerType == 3)
|
|
|
|
Format(sQuery, sizeof(sQuery), "SELECT time FROM playtimezr WHERE auth = '%d'", iAuthID);
|
|
|
|
|
2019-10-02 22:22:06 +02:00
|
|
|
g_hDatabase.Query(SQL_OnQueryCompletedTime, sQuery, GetClientSerial(client));
|
|
|
|
|
|
|
|
return Plugin_Handled;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Action Command_TopTime(int client, int args)
|
|
|
|
{
|
|
|
|
char sQuery[255];
|
2019-10-19 15:49:25 +02:00
|
|
|
|
|
|
|
if(g_iServerType == 1)
|
|
|
|
Format(sQuery, sizeof(sQuery), "SELECT * from playtimeze order by time desc limit 12");
|
|
|
|
else if(g_iServerType == 2)
|
|
|
|
Format(sQuery, sizeof(sQuery), "SELECT * from playtimemg order by time desc limit 12");
|
|
|
|
else if(g_iServerType == 3)
|
|
|
|
Format(sQuery, sizeof(sQuery), "SELECT * from playtimezr order by time desc limit 12");
|
|
|
|
|
2019-10-02 22:22:06 +02:00
|
|
|
g_hDatabase.Query(SQL_OnQueryCompletedTopTime, sQuery, GetClientSerial(client));
|
|
|
|
|
|
|
|
return Plugin_Handled;
|
|
|
|
}
|
|
|
|
|
2019-10-19 15:08:48 +02:00
|
|
|
public void OnClientAuthorized(int client)
|
2019-10-02 22:22:06 +02:00
|
|
|
{
|
|
|
|
if(IsValidClient(client))
|
2019-10-19 15:08:48 +02:00
|
|
|
{
|
|
|
|
g_bPlayerValid[client] = true;
|
2019-10-02 22:22:06 +02:00
|
|
|
g_iConnectionTime[client] = GetTime();
|
2019-10-19 15:08:48 +02:00
|
|
|
}
|
2019-10-02 22:22:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void OnClientDisconnect(int client)
|
|
|
|
{
|
2019-10-19 15:08:48 +02:00
|
|
|
if(g_iConnectionTime[client] == 0 || !g_bPlayerValid[client])
|
2019-10-02 22:22:06 +02:00
|
|
|
return;
|
|
|
|
|
2019-10-19 15:08:48 +02:00
|
|
|
g_bPlayerValid[client] = false;
|
|
|
|
|
2019-10-02 22:22:06 +02:00
|
|
|
int iPlayTime = GetTime() - g_iConnectionTime[client];
|
|
|
|
|
|
|
|
int iAuthID = GetSteamAccountID(client);
|
2019-10-03 23:48:45 +02:00
|
|
|
|
2019-10-03 16:33:10 +02:00
|
|
|
if(iAuthID == 0)
|
|
|
|
return;
|
2019-10-03 23:48:45 +02:00
|
|
|
|
2019-10-03 14:29:34 +02:00
|
|
|
char sName[MAX_NAME_LENGTH];
|
|
|
|
GetClientName(client, sName, sizeof(sName));
|
|
|
|
char sSafeName[(2*MAX_NAME_LENGTH)+1];
|
|
|
|
g_hDatabase.Escape(sName, sSafeName, sizeof(sSafeName));
|
2019-10-02 22:22:06 +02:00
|
|
|
|
|
|
|
char sQuery[512];
|
2019-10-19 15:49:25 +02:00
|
|
|
|
|
|
|
if(g_iServerType == 1)
|
|
|
|
Format(sQuery, sizeof(sQuery), "INSERT INTO playtimeze (auth,name,time) VALUES ('%u', '%s', '%d') ON DUPLICATE KEY UPDATE time=time+%d", iAuthID, sSafeName, iPlayTime, iPlayTime);
|
|
|
|
else if(g_iServerType == 2)
|
|
|
|
Format(sQuery, sizeof(sQuery), "INSERT INTO playtimemg (auth,name,time) VALUES ('%u', '%s', '%d') ON DUPLICATE KEY UPDATE time=time+%d", iAuthID, sSafeName, iPlayTime, iPlayTime);
|
|
|
|
else if(g_iServerType == 3)
|
|
|
|
Format(sQuery, sizeof(sQuery), "INSERT INTO playtimezr (auth,name,time) VALUES ('%u', '%s', '%d') ON DUPLICATE KEY UPDATE time=time+%d", iAuthID, sSafeName, iPlayTime, iPlayTime);
|
2019-10-02 22:22:06 +02:00
|
|
|
|
|
|
|
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];
|
2019-10-19 15:49:25 +02:00
|
|
|
|
|
|
|
if(g_iServerType == 1)
|
|
|
|
Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS playtimeze (`auth` INTEGER UNSIGNED, `name` varchar(128), `time` INTEGER, PRIMARY KEY (`auth`), INDEX (`time`))");
|
|
|
|
else if(g_iServerType == 2)
|
|
|
|
Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS playtimemg (`auth` INTEGER UNSIGNED, `name` varchar(128), `time` INTEGER, PRIMARY KEY (`auth`), INDEX (`time`))");
|
|
|
|
else if(g_iServerType == 3)
|
|
|
|
Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS playtimezr (`auth` INTEGER UNSIGNED, `name` varchar(128), `time` INTEGER, PRIMARY KEY (`auth`), INDEX (`time`))");
|
2019-10-02 22:22:06 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2019-10-05 18:04:17 +02:00
|
|
|
char sTitle[64];
|
2019-10-19 15:49:25 +02:00
|
|
|
if(g_iServerType == 1)
|
|
|
|
Format(sTitle, sizeof(sTitle), "[UNLOZE Playtime Zombie Escape] Player %N:", client);
|
|
|
|
else if(g_iServerType == 2)
|
|
|
|
Format(sTitle, sizeof(sTitle), "[UNLOZE Playtime Minigames] Player %N:", client);
|
|
|
|
else if(g_iServerType == 3)
|
|
|
|
Format(sTitle, sizeof(sTitle), "[UNLOZE Playtime Zombie Riot] Player %N:", client);
|
2019-10-05 18:04:17 +02:00
|
|
|
|
|
|
|
Panel mSayPanel = new Panel(GetMenuStyleHandle(MenuStyle_Radio));
|
|
|
|
|
|
|
|
mSayPanel.SetTitle(sTitle);
|
|
|
|
mSayPanel.DrawItem("", ITEMDRAW_SPACER);
|
|
|
|
mSayPanel.DrawText(sTime);
|
|
|
|
mSayPanel.DrawItem("", ITEMDRAW_SPACER);
|
|
|
|
mSayPanel.DrawText("(Data collected since Octobre 2019)");
|
|
|
|
mSayPanel.DrawItem("", ITEMDRAW_SPACER);
|
|
|
|
mSayPanel.DrawItem("1. Got it!", ITEMDRAW_RAWLINE);
|
|
|
|
mSayPanel.SetKeys(1023);
|
|
|
|
|
|
|
|
mSayPanel.Send(client, Handler_Menu, 0);
|
|
|
|
delete mSayPanel;
|
2019-10-02 22:22:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
2019-10-03 23:48:45 +02:00
|
|
|
Panel mSayPanel = new Panel(GetMenuStyleHandle(MenuStyle_Radio));
|
2019-10-19 15:49:25 +02:00
|
|
|
|
|
|
|
if(g_iServerType == 1)
|
|
|
|
mSayPanel.SetTitle("[UNLOZE Playtime] Record Holders Zombie Escape:");
|
|
|
|
else if(g_iServerType == 2)
|
|
|
|
mSayPanel.SetTitle("[UNLOZE Playtime] Record Holders Minigames:");
|
|
|
|
else if(g_iServerType == 3)
|
|
|
|
mSayPanel.SetTitle("[UNLOZE Playtime] Record Holders Zombie Riot:");
|
|
|
|
|
2019-10-03 23:48:45 +02:00
|
|
|
mSayPanel.DrawItem("", ITEMDRAW_SPACER);
|
|
|
|
|
2019-10-02 22:22:06 +02:00
|
|
|
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);
|
2019-10-04 00:49:09 +02:00
|
|
|
iTime[i - 1] = iTime[i - 1] / 60;
|
2019-10-02 22:22:06 +02:00
|
|
|
|
|
|
|
Format(sBuffer[i - 1], 128, "%d. %s - %d Minutes", i, sName[i - 1], iTime[i - 1]);
|
2019-10-03 23:48:45 +02:00
|
|
|
mSayPanel.DrawText(sBuffer[i - 1]);
|
2019-10-02 22:22:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mSayPanel.DrawItem("", ITEMDRAW_SPACER);
|
2019-10-03 23:48:45 +02:00
|
|
|
mSayPanel.DrawItem("1. Got it!", ITEMDRAW_RAWLINE);
|
2019-10-02 22:22:06 +02:00
|
|
|
|
2019-10-03 23:48:45 +02:00
|
|
|
mSayPanel.SetKeys(1023);
|
|
|
|
mSayPanel.Send(client, Handler_Menu, 0);
|
2019-10-02 22:22:06 +02:00
|
|
|
delete mSayPanel;
|
|
|
|
}
|
|
|
|
|
2019-10-03 23:48:45 +02:00
|
|
|
public int Handler_Menu(Menu menu, MenuAction action, int param1, int param2)
|
2019-10-02 22:22:06 +02:00
|
|
|
{
|
2019-10-03 23:48:45 +02:00
|
|
|
switch(action)
|
|
|
|
{
|
|
|
|
case MenuAction_Select, MenuAction_Cancel:
|
|
|
|
delete menu;
|
|
|
|
}
|
2019-10-02 22:22:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
stock bool IsValidClient(int client)
|
|
|
|
{
|
2019-10-19 15:08:48 +02:00
|
|
|
return (client >= 1 && client <= MaxClients && !IsFakeClient(client) && PM_IsPlayerSteam(client));
|
2019-10-02 22:22:06 +02:00
|
|
|
}
|