Code:
#include <sourcemod>
#include <sdkhooks>
#include <sdktools>
new const String:PLUGIN_VERSION[] = "1.0";
#define SECONDS_IN_A_WEEK 604800
#define SECONDS_IN_A_DAY 86400
// Offset adds to reset time, this to allow resetting on a Monday rather than a Sunday.
#define DAYS_OFFSET 0
public Plugin:myinfo =
{
name = "WePlay - Admin Play Time",
author = "Eyal282",
description = "xoxoxoxoxoxoxooxoxoxoxooxoxoxo",
version = PLUGIN_VERSION,
url = ""
}
// This means that if someone is connected for 4 seconds and disconnects, it's like he never connected. This cannot be a float.
#define TIME_REGISTER_DELAY 5
new Handle:dbTime;
new bool:PostAdminCheck[MAXPLAYERS+1];
public OnPluginStart()
{
ConnectToDatabase();
RegAdminCmd("sm_times", Command_Times, ADMFLAG_ROOT, "Shows a menu of admins sorted by their time online");
RegAdminCmd("sm_time", Command_Time, ADMFLAG_GENERIC, "Prints your play time this week");
}
public ConnectToDatabase()
{
new String:Error[256];
if((dbTime = SQLite_UseDatabase("AdminTime", Error, sizeof(Error))) == INVALID_HANDLE)
LogError(Error);
else
{
SQL_TQuery(dbTime, SQLCB_Error, "CREATE TABLE IF NOT EXISTS AdminTime_players (AuthId VARCHAR(64) NOT NULL UNIQUE, Name VARCHAR(64) NOT NULL, SecondsInGame INT(15) NOT NULL, isAdmin INT(3) NOT NULL)", _, DBPrio_High);
SQL_TQuery(dbTime, SQLCB_Error, "CREATE TABLE IF NOT EXISTS AdminTime_serverVariables (LastResetTimestamp INT(15) NOT NULL)", _, DBPrio_High);
SQL_TQuery(dbTime, SQLCB_Error, "INSERT OR IGNORE INTO AdminTime_serverVariables (LastResetTimestamp) VALUES (0)", _, DBPrio_High);
CreateTimer(0.0, Timer_CheckReset, _, TIMER_FLAG_NO_MAPCHANGE);
}
}
public Action:Timer_CheckReset(Handle:hTimer)
{
SQL_TQuery(dbTime, SQLCB_CheckReset, "SELECT * FROM AdminTime_serverVariables");
}
public SQLCB_CheckReset(Handle:db, Handle:hndl, const String:sError[], data)
{
if(hndl == null)
ThrowError(sError);
else if(SQL_GetRowCount(hndl) == 0)
{
ResetAdminTimes();
return;
}
new LastResetTimestamp = SQL_FetchInt(hndl, 0);
if(GetTime() - LastResetTimestamp > SECONDS_IN_A_WEEK)
ResetAdminTimes();
else
CreateTimer(float(SECONDS_IN_A_WEEK - LastResetTimestamp - GetTime()), Timer_CheckReset, _, TIMER_FLAG_NO_MAPCHANGE);
}
ResetAdminTimes()
{
new String:sQuery[256];
new LastResetTimestamp = GetTime() % SECONDS_IN_A_WEEK;
// +5 Because something related to Unix starting at Thursday.
new DayOfWeek = RoundToFloor(float(LastResetTimestamp) / 86400.0) + 5;
LastResetTimestamp = GetTime() - ((DayOfWeek-DAYS_OFFSET) * SECONDS_IN_A_DAY);
DayOfWeek = RoundToFloor(float(LastResetTimestamp % SECONDS_IN_A_WEEK) / 86400.0) + 5;
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "DROP TABLE IF EXISTS AdminTime_players_lastWeek");
SQL_TQuery(dbTime, SQLCB_Error, sQuery, _, DBPrio_High);
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "UPDATE AdminTime_serverVariables SET LastResetTimestamp = %i", LastResetTimestamp);
SQL_TQuery(dbTime, SQLCB_Error, sQuery, _, DBPrio_High);
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "ALTER TABLE AdminTime_players RENAME TO AdminTime_players_lastWeek");
SQL_TQuery(dbTime, SQLCB_Error, sQuery, _, DBPrio_High);
ConnectToDatabase();
}
public SQLCB_Error(Handle:db, Handle:hndl, const String:sError[], data)
{
if(hndl == null)
ThrowError(sError);
}
public OnClientConnected(client)
{
PostAdminCheck[client] = false;
}
public OnClientAuthorized(client)
{
new String:AuthId[35];
GetClientAuthId(client, AuthId_Engine, AuthId, sizeof(AuthId));
new String:sQuery[256];
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "INSERT OR IGNORE INTO AdminTime_players (AuthId, Name, SecondsInGame, isAdmin) VALUES ('%s', '%N', 0, 0)", AuthId, client);
SQL_TQuery(dbTime, SQLCB_Error, sQuery);
CreateTimer(float(TIME_REGISTER_DELAY), Timer_RegisterTime, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
}
public OnClientPostAdminCheck(client)
{
PostAdminCheck[client] = true;
new String:AuthId[35];
new String:sQuery[256];
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "UPDATE AdminTime_players SET isAdmin = %i WHERE AuthId = '%s'", CheckCommandAccess(client, "sm_admin", ADMFLAG_GENERIC), AuthId);
SQL_TQuery(dbTime, SQLCB_Error, sQuery, _, DBPrio_Normal);
}
public Action:Timer_RegisterTime(Handle:hTimer, UserId)
{
new client = GetClientOfUserId(UserId);
if(client == 0)
return Plugin_Stop;
new String:AuthId[35];
GetClientAuthId(client, AuthId_Engine, AuthId, sizeof(AuthId));
new String:sQuery[256];
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "UPDATE AdminTime_players SET SecondsInGame = SecondsInGame + %i, Name = '%N' WHERE AuthId = '%s'", TIME_REGISTER_DELAY, client, AuthId);
SQL_TQuery(dbTime, SQLCB_Error, sQuery, _, DBPrio_Normal);
return Plugin_Continue;
}
public Action:Command_Time(client, args)
{
new String:sQuery[256];
new String:AuthId[35];
GetClientAuthId(client, AuthId_Engine, AuthId, sizeof(AuthId));
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "SELECT * FROM AdminTime_players WHERE AuthId = '%s'", AuthId);
SQL_TQuery(dbTime, SQLCB_ShowYourTime, sQuery, GetClientUserId(client), DBPrio_High);
return Plugin_Handled;
}
public SQLCB_ShowYourTime(Handle:db, Handle:hndl, const String:sError[], UserId)
{
if(hndl == null)
ThrowError(sError);
else if(SQL_GetRowCount(hndl) == 0)
return;
new client = GetClientOfUserId(UserId);
if(client == 0)
return;
else if(!SQL_FetchRow(hndl))
return;
new SecondsInGame = SQL_FetchInt(hndl, 2);
new String:Time[32];
FormatTimeHMS(Time, sizeof(Time), SecondsInGame);
PrintToChat(client, "Play Time: %s", Time);
}
public Action:Command_Times(client, args)
{
new Handle:hMenu = CreateMenu(Times_MenuHandler);
AddMenuItem(hMenu, "", "Weekly Admin Times");
AddMenuItem(hMenu, "", "Last Week Admin Times");
AddMenuItem(hMenu, "", "Reset Admin Time", CheckCommandAccess(client, "sm_checkcommandaccess_root", ADMFLAG_ROOT, true) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED);
DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
return Plugin_Handled;
}
public Times_MenuHandler(Handle:hMenu, MenuAction:action, client, item)
{
if(action == MenuAction_End)
CloseHandle(hMenu);
else if(action == MenuAction_Select)
{
switch(item)
{
case 0: ShowAdminTimes(client);
case 1: ShowAdminTimes(client, true);
case 2: ResetAdminTimes();
}
}
}
ShowAdminTimes(client, bool:lastWeek = false)
{
new String:sQuery[256];
SQL_FormatQuery(dbTime, sQuery, sizeof(sQuery), "SELECT * FROM %s WHERE isAdmin = 1 ORDER BY SecondsInGame DESC", lastWeek ? "AdminTime_players_lastWeek" : "AdminTime_players");
SQL_TQuery(dbTime, SQLCB_MakeAdminTimeMenu, sQuery, GetClientUserId(client), DBPrio_High);
}
public SQLCB_MakeAdminTimeMenu(Handle:db, Handle:hndl, const String:sError[], UserId)
{
if(hndl == null)
ThrowError(sError);
else if(SQL_GetRowCount(hndl) == 0)
return;
new client = GetClientOfUserId(UserId);
if(client == 0)
return;
new Handle:hMenu = CreateMenu(Dummy_MenuHandler);
while(SQL_FetchRow(hndl))
{
new String:Name[64];
SQL_FetchString(hndl, 1, Name, sizeof(Name));
new SecondsInGame = SQL_FetchInt(hndl, 2);
new String:TempFormat[128], String:Time[32];
FormatTimeHMS(Time, sizeof(Time), SecondsInGame);
Format(TempFormat, sizeof(TempFormat), "%s [%s]", Name, Time);
AddMenuItem(hMenu, "", TempFormat);
}
SetMenuExitBackButton(hMenu, true);
SetMenuTitle(hMenu, "List of Admins sorted by most to least active");
DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
}
public Dummy_MenuHandler(Handle:hMenu, MenuAction:action, client, item)
{
if(action == MenuAction_End)
CloseHandle(hMenu);
else if(action == MenuAction_Cancel && item == MenuCancel_ExitBack)
{
Command_Times(client, 0);
}
}
stock FormatTimeHMS(char[] Time, length, timestamp, bool:LimitTo24H = false)
{
if(LimitTo24H)
{
if(timestamp >= 86400)
timestamp %= 86400;
}
new HH, MM, SS;
HH = timestamp / 3600
MM = timestamp % 3600 / 60
SS = timestamp % 3600 % 60
Format(Time, length, "%02d:%02d:%02d", HH, MM, SS);
}
It just erases everything for some reason. I want every week to delete the table of last week and rename a table to be of last week, then use the ConnectToDatabase to recreate this week's table. What am I doing wrong that causes last week's data to be unavaiable?