projects-jenz/discord_verificiation/scripting/unloze_player_time.sp

963 lines
29 KiB
SourcePawn

#pragma semicolon 1
#define PLUGIN_AUTHOR "jenz"
#define PLUGIN_VERSION "1.4"
#include <sourcemod>
#include <cstrike>
#include <PlayerManager>
#include <AFKManager>
Database g_hDatabase;
//check if autismbot
bool is_bot_player[MAXPLAYERS + 1];
Handle g_h_time_activity = null;
char g_csSID[MAXPLAYERS + 1][65];
char g_cTimeRecords[1000][128];
int g_iPlayerTimeServer[MAXPLAYERS + 1];
int g_iPlayerAFKTime;
int g_iPlayerCount_excludeSpec;
int g_iPlayerRTVCapacity;
int g_iAvgHour_Contribution_per_player;
int g_iRtvBoost_tier;
int g_iPlayerTier[MAXPLAYERS + 1];
StringMap g_GroupOverrides; // group name -> comma-separated override list
static Handle g_hForwardPlayerHours;
static Handle g_hForwardPlayerTier;
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)
{
return Plugin_Continue;
}
char sServer[64];
int i_port = GetConVarInt(FindConVar("hostport"));
if (i_port == 27015 || i_port == 27035) //might as well count play time on ze2. it was not done before but its a bit like why not anyways.
{
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
{
return Plugin_Continue;
}
for (int client = 1; client <= MaxClients; client++)
{
if (IsValidClient(client) && !IsFakeClient(client) && IsPlayerAlive(client))
{
char sIP[32];
GetClientIP(client, sIP, sizeof(sIP));
char sQuery[512];
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 where steam_id = '%s' and ipv4 = '%s'", sServer, sServer, g_csSID[client], sIP);
g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low);
Format(sQuery, sizeof(sQuery), "update unloze_playtimestats.player_time set player_name = '%s' where steam_id = '%s' and player_name != '%s'", sEscapedName, g_csSID[client], sEscapedName);
g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low);
}
}
return Plugin_Continue;
}
public void LoadGroupOverrides()
{
KeyValues kv = new KeyValues("Groups");
char path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "configs/admin_groups.cfg");
if (!kv.ImportFromFile(path))
{
delete kv;
return;
}
// collect group names first
char groupNames[32][64];
int groupCount = 0;
if (kv.GotoFirstSubKey())
{
do
{
char sName[64];
kv.GetSectionName(sName, sizeof(sName));
if (StrContains(sName, "tier", false) == 0)
{
strcopy(groupNames[groupCount], 64, sName);
groupCount++;
}
}
while (kv.GotoNextKey() && groupCount < 32);
}
// now for each group, rewind and re-navigate fresh
for (int i = 0; i < groupCount; i++)
{
kv.Rewind();
if (!kv.JumpToKey(groupNames[i]))
continue;
if (!kv.JumpToKey("Overrides"))
continue;
if (!kv.GotoFirstSubKey(false))
continue;
char overrideList[512];
overrideList[0] = '\0';
do
{
char cmd[64];
kv.GetSectionName(cmd, sizeof(cmd));
if (overrideList[0] != '\0')
StrCat(overrideList, sizeof(overrideList), ", ");
StrCat(overrideList, sizeof(overrideList), cmd);
}
while (kv.GotoNextKey(false));
g_GroupOverrides.SetString(groupNames[i], overrideList);
}
delete kv;
}
public void OnPluginStart()
{
g_GroupOverrides = new StringMap();
LoadGroupOverrides();
if (!g_hDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "unloze_playtimestats");
}
RegConsoleCmd("sm_playtime", Command_Time, "retreives total connection time on all connected servers");
RegConsoleCmd("sm_tier", Command_Tier, "shows what tier features you have");
RegConsoleCmd("sm_topplaytime", Command_TopTime, "retreives top 1000 playtime highscores on all connected servers");
g_h_time_activity = CreateTimer(10.0, time_query_activity, INVALID_HANDLE, TIMER_REPEAT);
CreateTimer(600.0, UpdateForward, _, 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;
ConVar cvar1;
HookConVarChange((cvar1 = CreateConVar("sm_exclude_specs_avghour", "20", "How many players must be considered active on the server before specs are included in generating the average hour count")), Cvar_playerExcludeSpec);
g_iPlayerCount_excludeSpec = cvar1.IntValue;
delete cvar1;
ConVar cvar2;
HookConVarChange((cvar2 = CreateConVar("sm_rtv_avg_capacity", "5", "The capacity for how many times the average a players rtv can be worth.")), Cvar_playerRTVAverageCap);
g_iPlayerRTVCapacity = cvar2.IntValue;
delete cvar2;
ConVar cvar3;
HookConVarChange((cvar3 = CreateConVar("sm_avg_hour_contribution_per_player", "5000", "How many hours maximum each player can contribute to averagehours")), Cvar_AverageHourContribution);
g_iAvgHour_Contribution_per_player = cvar3.IntValue;
delete cvar3;
ConVar cvar4;
HookConVarChange((cvar4 = CreateConVar("sv_rtv_boost_tier", "4", "which tier for giving the rtv/mapvote/nominations boost")), Cvar_RTVBoostTier);
g_iRtvBoost_tier = cvar4.IntValue;
delete cvar3;
}
public Action UpdateForward(Handle timer)
{
for (int i = 0; i < MaxClients; i++)
{
if (IsValidClient(i) && !IsFakeClient(i) && !IsClientSourceTV(i) && !is_bot_player[i])
{
select_client_time_server(i);
}
}
return Plugin_Handled;
}
public void Cvar_playerAFKTime(ConVar convar, const char[] oldValue, const char[] newValue)
{
g_iPlayerAFKTime = convar.IntValue;
}
public void Cvar_playerExcludeSpec(ConVar convar, const char[] oldValue, const char[] newValue)
{
g_iPlayerCount_excludeSpec = convar.IntValue;
}
public void Cvar_playerRTVAverageCap(ConVar convar, const char[] oldValue, const char[] newValue)
{
g_iPlayerRTVCapacity = convar.IntValue;
}
public void Cvar_AverageHourContribution(ConVar convar, const char[] oldValue, const char[] newValue)
{
g_iAvgHour_Contribution_per_player = convar.IntValue;
}
public void Cvar_RTVBoostTier(ConVar convar, const char[] oldValue, const char[] newValue)
{
g_iRtvBoost_tier = convar.IntValue;
}
public APLRes AskPluginLoad2(Handle myself, bool late, char [] error, int err_max)
{
CreateNative("GetAveragePlayerTimeOnServer", Native_GetAveragePlayerActiveTimeServer);
CreateNative("GetPlayerWorthRTV_boost_", Native_GetPlayerWorthRTV_boost);
g_hForwardPlayerHours = CreateGlobalForward("GetPlayerHoursServer", ET_Ignore, Param_Cell, Param_Cell, Param_Cell);
g_hForwardPlayerTier = CreateGlobalForward("GetPlayerTier", ET_Ignore, Param_Cell, Param_Cell);
return APLRes_Success;
}
public int GetAveragePlayerActiveTimeServer()
{
int total_hours = 0;
int total_players = 0;
int active_player_count = 0;
for (int i = 0; i < MaxClients; i++)
{
//checking player count before deciding if including or excluding spectators from actual average
//the purpose of this is me (jenz) not boosting the hour average insanely when the server is very empty. (i often sit spec without playing and that ruins the generated average when low population because the count gets way too high due to me)
if (IsValidClient(i) && !IsFakeClient(i) && !IsClientSourceTV(i) && !is_bot_player[i]
&& (GetClientTeam(i) == CS_TEAM_T || GetClientTeam(i) == CS_TEAM_CT))
{
active_player_count++;
}
}
for (int i = 0; i < MaxClients; i++)
{
if (IsValidClient(i) && !IsFakeClient(i) && !IsClientSourceTV(i) && !is_bot_player[i] && GetClientIdleTime(i) < g_iPlayerAFKTime)
{
if (active_player_count < g_iPlayerCount_excludeSpec && GetClientTeam(i) != CS_TEAM_T && GetClientTeam(i) != CS_TEAM_CT)
{
continue;
}
//re-introducing the hour capacity but putting it here is better than putting it at the mysql query
//at the time of making this change its only affeting me jenz and nobody else. this is meant to prevent
//the average hour from being too skewed by high playtime people.
int added_hours = g_iPlayerTimeServer[i] > g_iAvgHour_Contribution_per_player ? g_iAvgHour_Contribution_per_player : g_iPlayerTimeServer[i];
total_hours += added_hours;
total_players++;
}
}
if (total_hours == 0)
{
return 0;
}
return total_hours / total_players;
}
public int Native_GetAveragePlayerActiveTimeServer(Handle plugin, int numParams)
{
return GetAveragePlayerActiveTimeServer();
}
public int Native_GetPlayerWorthRTV_boost(Handle plugin, int numParams)
{
int client = GetNativeCell(1);
if(client > MaxClients || client <= 0)
{
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
return view_as<int>(-1);
}
if(!IsClientInGame(client))
{
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
return view_as<int>(-1);
}
int avg = GetAveragePlayerActiveTimeServer();
//give tier the rtv/nomination/mapvote boost
if (g_iPlayerTier[client] >= g_iRtvBoost_tier)
{
return g_iPlayerRTVCapacity;
}
if (g_iPlayerTimeServer[client] <= avg || avg == 0 || is_bot_player[client] || IsFakeClient(client))
{
return 1;
}
if ((float(g_iPlayerTimeServer[client]) / float(avg)) > g_iPlayerRTVCapacity)
{
return g_iPlayerRTVCapacity; //1.0-5.0 booster probably
}
int val = RoundToFloor((g_iPlayerTimeServer[client]) / float(avg));
if (val < 1)
{
val = 1;
}
return val;
}
public void OnPluginEnd()
{
if (g_h_time_activity != null)
delete g_h_time_activity;
CloseHandle(g_hForwardPlayerHours);
CloseHandle(g_hForwardPlayerTier);
}
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++)
{
if(IsValidClient(i) && !IsFakeClient(i))
{
OnClientPostAdminCheck(i);
}
}
OnMapStart();
}
public void OnClientPostAdminCheck(int client)
{
GetClientAuthId(client, AuthId_Steam2, g_csSID[client], sizeof(g_csSID[]));
is_bot_player[client] = false;
g_iPlayerTier[client] = -1;
g_iPlayerTimeServer[client] = 0;
if(!IsValidClient(client) || IsFakeClient(client))
return;
if (!g_hDatabase)
{
return;
}
insert_client(client);
select_client_time_server(client);
if (StrEqual("[U:1:1221121532]", g_csSID[client], false) || StrEqual("STEAM_0:0:610560766", g_csSID[client], false))
{
is_bot_player[client] = true;
}
if (StrEqual("[U:1:408797742]", g_csSID[client], false) || StrEqual("STEAM_0:0:204398871", g_csSID[client], false))
{
is_bot_player[client] = true;
}
if (StrEqual("[U:1:1036189204]", g_csSID[client], false) || StrEqual("STEAM_0:0:518094602", g_csSID[client], false))
{
is_bot_player[client] = true;
}
if (StrEqual("[U:1:120378081]", g_csSID[client], false) || StrEqual("STEAM_0:1:60189040", g_csSID[client], 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 || i_port == 27035)
{
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
{
return;
}
char sQuery[512];
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, g_csSID[client], sServer);
g_hDatabase.Query(SQL_OnQueryCompletedTimeServer, sQuery, GetClientSerial(client), DBPrio_High);
}
public void SQL_OnQueryCompletedTimeServer(Database db, DBResultSet results, const char[] error, int iSerial)
{
if (!db || strlen(error))
{
delete results;
LogError("Query error 3: %s", error);
return;
}
int client;
if ((client = GetClientFromSerial(iSerial)) == 0)
{
delete results;
return;
}
int iTime_Server;
while (results.RowCount && results.FetchRow())
{
iTime_Server += results.FetchInt(0);
}
delete results;
int iHours_Server = (iTime_Server / 60) / 60;
int iMinutes_Server = (iTime_Server / 60) % 60;
g_iPlayerTimeServer[client] = iHours_Server;
Call_StartForward(g_hForwardPlayerHours);
Call_PushCell(client);
Call_PushCell(g_iPlayerTimeServer[client]);
Call_PushCell(iMinutes_Server);
Call_Finish();
if (g_iPlayerTier[client] == -1)
{
SetPlayerTier(client);
if (g_iPlayerTier[client] > 0)
{
WritePlayerTierToFile(client); //checks if all tiers have to be written
}
}
else if (check_if_client_new_tier(client)) //called every 10 minutes to fill new times from DB
{
SetPlayerTier(client);
WritePlayerTierToFile(client); //write only the new tier to the file at the end.
}
}
public void WritePlayerTierToFile(int client)
{
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "configs/admins_simple.ini");
// --- Read entire file into memory ---
File f = OpenFile(sPath, "r");
if (!f)
{
LogError("WritePlayerTierToFile: failed to open %s for reading", sPath);
return;
}
bool foundSeparator = false;
//always write the steamIDs as steamID 2 format.
char sSID[64];
GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
bool write_all_tiers = true;
bool write_newest_tier = false;
char line[256];
while (f.ReadLine(line, sizeof(line)))
{
int len = strlen(line);
while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r'))
line[--len] = '\0';
if (StrEqual(line, "//here begins the unloze_play_time plugin tiers", false))
{
foundSeparator = true;
continue;
}
if (!foundSeparator)
{
continue;
}
// Each line looks like: "STEAM_0:0:12345" "@tier3"
// Extract steam ID and tier number
char steamid[65];
char group[64];
int pos = 1; //skip opening quote
int sidStart = pos;
while (line[pos] != '"')
{
pos++;
}
int sidLen = pos - sidStart;
strcopy(steamid, sidLen + 1, line[sidStart]);
if (!StrEqual(steamid, sSID))
{
continue;
}
//if steam ID does not exist write all tiers
write_all_tiers = false;
write_newest_tier = true;
pos++; // skip closing quote of steamid
while (line[pos] == ' ' || line[pos] == '\t') pos++; // skip whitespace
pos++; // skip opening quote of group
int grpStart = pos;
while (line[pos] != '"') pos++;
int grpLen = pos - grpStart;
strcopy(group, grpLen + 1, line[grpStart]);
// group is "@tier3", extract tier number
char tierStr[8];
strcopy(tierStr, sizeof(tierStr), group[5]); // skip "@tier"
int tierNum = StringToInt(tierStr);
if (tierNum == g_iPlayerTier[client])
{
write_newest_tier = false;
break; //we confirmed the most recent tier was already written here.
}
}
delete f;
if (write_all_tiers)
{
// Open file for appending
File fAppend = OpenFile(sPath, "a");
for (int t = 1; t <= g_iPlayerTier[client]; t++)
{
char linewrite[256];
Format(linewrite, sizeof(linewrite), "\"%s\" \"@tier%i\"\n", sSID, t);
fAppend.WriteString(linewrite, false);
}
delete fAppend;
SetTierRewards(client);
}
else if (write_newest_tier)
{
// Open file for appending
File fAppend = OpenFile(sPath, "a");
char linewrite[256];
Format(linewrite, sizeof(linewrite), "\"%s\" \"@tier%i\"\n", sSID, g_iPlayerTier[client]);
fAppend.WriteString(linewrite, false);
delete fAppend;
SetTierRewards(client);
}
}
public bool check_if_client_new_tier(int client)
{
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "configs/unloze_playt_time_tiers.cfg");
KeyValues kv = new KeyValues("PlayTimeTiers");
if (!kv.ImportFromFile(sPath))
{
LogError("configs/unloze_playt_time_tiers not found");
delete kv;
return false;
}
if (!kv.GotoFirstSubKey(false))
{
LogError("configs/unloze_playt_time_tiers.cfg is empty or malformed");
delete kv;
return false;
}
bool upgrade_tier = false;
do
{
char sKey[16], sVal[16];
kv.GetSectionName(sKey, sizeof(sKey));
kv.GetString(NULL_STRING, sVal, sizeof(sVal), "-1");
int tier = StringToInt(sVal);
int hours = StringToInt(sKey);
if (hours > g_iPlayerTimeServer[client])
{
break;
}
if (tier > g_iPlayerTier[client])
{
PrintToChatAll("%N Leveled up to Tier: %i!", client, tier);
upgrade_tier = true;
}
} while (kv.GotoNextKey(false));
delete kv;
return upgrade_tier;
}
public void SetTierRewards(int client)
{
if (g_iPlayerTier[client] < 1)
{
return;
}
for (int i = 1; i <= g_iPlayerTier[client]; i++)
{
char groupname[64];
Format(groupname, sizeof(groupname), "tier%i", i);
AddClientToGroup(client, groupname);
}
}
public void AddClientToGroup(int client, const char[] groupName)
{
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID)
{
id = CreateAdmin();
SetUserAdmin(client, id, true);
}
GroupId grp = FindAdmGroup(groupName);
if (grp == INVALID_GROUP_ID)
{
grp = CreateAdmGroup(groupName);
}
AdminInheritGroup(id, grp);
}
public void SetPlayerTier(int client)
{
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "configs/unloze_playt_time_tiers.cfg");
KeyValues kv = new KeyValues("PlayTimeTiers");
if (!kv.ImportFromFile(sPath))
{
LogError("configs/unloze_playt_time_tiers not found");
delete kv;
return;
}
if (!kv.GotoFirstSubKey(false))
{
LogError("configs/unloze_playt_time_tiers.cfg is empty or malformed");
delete kv;
return;
}
int next_hours = 0;
do
{
char sKey[16], sVal[16];
kv.GetSectionName(sKey, sizeof(sKey));
kv.GetString(NULL_STRING, sVal, sizeof(sVal), "-1");
int tier = StringToInt(sVal);
int hours = StringToInt(sKey);
next_hours = hours;
if (hours > g_iPlayerTimeServer[client])
{
break;
}
g_iPlayerTier[client] = tier;
} while (kv.GotoNextKey(false));
if (g_iPlayerTier[client] == -1)
{
g_iPlayerTier[client] = 0;
}
Call_StartForward(g_hForwardPlayerTier);
Call_PushCell(client);
Call_PushCell(g_iPlayerTier[client]);
Call_Finish();
if (g_iPlayerTimeServer[client] < next_hours)
{
PrintToChat(client, "You need %i hours to reach next tier. Check your features with !sm_tier", next_hours - g_iPlayerTimeServer[client]);
}
delete kv;
}
public void OnClientDisconnect(int client)
{
g_iPlayerTier[client] = -1;
Format(g_csSID[client], sizeof(g_csSID[]), "");
is_bot_player[client] = false;
g_iPlayerTimeServer[client] = 0;
}
public void insert_client(int client)
{
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'", g_csSID[client], 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 || i_port == 27035)
{
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
{
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 1000", 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 || i_port == 27035)
{
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 1000 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);
return Plugin_Handled;
}
public void PrintClientGroupOverrides(int client)
{
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID)
{
PrintToChat(client, "You have no tiers.");
return;
}
int groupCount = GetAdminGroupCount(id);
if (groupCount == 0)
{
PrintToChat(client, "You have no tiers.");
return;
}
char rtv_boost_tier[32];
Format(rtv_boost_tier, sizeof(rtv_boost_tier), "tier%i", g_iRtvBoost_tier);
for (int i = 0; i < groupCount; i++)
{
char groupName[64];
GroupId grp = GetAdminGroup(id, i, groupName, sizeof(groupName));
if (grp == INVALID_GROUP_ID)
continue;
char overrides[512];
if (StrEqual(groupName, rtv_boost_tier))
{
PrintToChat(client, "tier%i access: %i mapvote/rtv/nomination boost", g_iRtvBoost_tier, g_iPlayerRTVCapacity);
}
if (g_GroupOverrides.GetString(groupName, overrides, sizeof(overrides)))
{
PrintToChat(client, "%s access: %s", groupName, overrides);
}
}
PrintToChat(client, "any tier access: playermodels in zclass.");
}
public Action Command_Tier(int client, int args)
{
PrintClientGroupOverrides(client);
return Plugin_Handled;
}
public Action Command_Time(int client, int args)
{
if (!g_hDatabase)
{
return Plugin_Handled;
}
char sQuery[512];
Format(sQuery, sizeof(sQuery), "select ze_time, mg_time, zr_time, jb_time from unloze_playtimestats.player_time pt where pt.steam_id = '%s'", g_csSID[client]);
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))
{
delete results;
LogError("Query error 3: %s", error);
return;
}
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))
{
delete results;
LogError("Query error 3: %s", error);
return;
}
int client;
if ((client = GetClientFromSerial(iSerial)) == 0)
{
delete results;
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;
}
return 0;
}