Skip to content

Add FirstLogin column to database and profile #1234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum
Migration_DeprecateExactTimeInt,
Migration_AddPlayertimesAuthFK,
Migration_FixSQLiteMapzonesROWID,
Migration_AddUsersFirstLogin,
MIGRATIONS_END
};

Expand Down Expand Up @@ -87,6 +88,7 @@ char gS_MigrationNames[][] = {
"DeprecateExactTimeInt",
"AddPlayertimesAuthFK",
"FixSQLiteMapzonesROWID",
"AddUsersFirstLogin",
};

static Database gH_SQL;
Expand Down Expand Up @@ -133,13 +135,13 @@ public void SQL_CreateTables(Database hSQL, const char[] prefix, int driver)
if (driver == Driver_mysql)
{
FormatEx(sQuery, sizeof(sQuery),
"CREATE TABLE IF NOT EXISTS `%susers` (`auth` INT NOT NULL, `name` VARCHAR(32) COLLATE 'utf8mb4_general_ci', `ip` INT, `lastlogin` INT NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, `playtime` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`), INDEX `points` (`points`), INDEX `lastlogin` (`lastlogin`)) ENGINE=INNODB;",
"CREATE TABLE IF NOT EXISTS `%susers` (`auth` INT NOT NULL, `name` VARCHAR(32) COLLATE 'utf8mb4_general_ci', `ip` INT, `lastlogin` INT NOT NULL DEFAULT -1, `firstlogin` INT NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, `playtime` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`), INDEX `points` (`points`), INDEX `lastlogin` (`lastlogin`)) ENGINE=INNODB;",
gS_SQLPrefix);
}
else
{
FormatEx(sQuery, sizeof(sQuery),
"CREATE TABLE IF NOT EXISTS `%susers` (`auth` INT NOT NULL PRIMARY KEY, `name` VARCHAR(32), `ip` INT, `lastlogin` INTEGER NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, `playtime` FLOAT NOT NULL DEFAULT 0);",
"CREATE TABLE IF NOT EXISTS `%susers` (`auth` INT NOT NULL PRIMARY KEY, `name` VARCHAR(32), `ip` INT, `lastlogin` INTEGER NOT NULL DEFAULT -1, `firstlogin` INTEGER NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, `playtime` FLOAT NOT NULL DEFAULT 0);",
gS_SQLPrefix);
}

Expand Down Expand Up @@ -369,6 +371,7 @@ void ApplyMigration(int migration)
case Migration_DeprecateExactTimeInt: ApplyMigration_DeprecateExactTimeInt();
case Migration_AddPlayertimesAuthFK: ApplyMigration_AddPlayertimesAuthFK();
case Migration_FixSQLiteMapzonesROWID: ApplyMigration_FixSQLiteMapzonesROWID();
case Migration_AddUsersFirstLogin: ApplyMigration_AddUsersFirstLogin();
}
}

Expand Down Expand Up @@ -686,6 +689,27 @@ public void Trans_FixSQLiteMapzonesROWID_Error(Database db, any data, int numQue
LogError("Timer error! SQLiteMapzonesROWID migration transaction failed. Reason: %s", error);
}

void ApplyMigration_AddUsersFirstLogin()
{
char sQuery[256];
FormatEx(sQuery, sizeof(sQuery), "ALTER TABLE %susers ADD `firstlogin` INT NOT NULL DEFAULT -1 %s;", gS_SQLPrefix, (gI_Driver == Driver_mysql) ? "AFTER `lastlogin`" : "");
QueryLog(gH_SQL, ApplyMigration_AddUsersFirstLogin2222222_Callback, sQuery, Migration_AddUsersFirstLogin, DBPrio_High);
}

public void ApplyMigration_AddUsersFirstLogin2222222_Callback(Database db, DBResultSet results, const char[] error, any data)
{
char sQuery[256];
if(gI_Driver == Driver_mysql)
{
FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET firstlogin = IF((SELECT COUNT(*) FROM %splayertimes WHERE %splayertimes.auth = %susers.auth) > 0, (SELECT MIN(`date`) FROM %splayertimes WHERE auth = %susers.auth), IF((%susers.lastlogin != 0), %susers.lastlogin, UNIX_TIMESTAMP()));", gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix);
}
else
{
FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET firstlogin = IIF((SELECT COUNT(*) FROM %splayertimes WHERE %splayertimes.auth = %susers.auth) > 0, (SELECT MIN(`date`) FROM %splayertimes WHERE auth = %susers.auth), IIF((%susers.lastlogin != 0), %susers.lastlogin, unixepoch('now')));", gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix, gS_SQLPrefix);
}
QueryLog(gH_SQL, SQL_TableMigrationSingleQuery_Callback, sQuery, Migration_AddUsersFirstLogin, DBPrio_High);
}

public void SQL_TableMigrationSingleQuery_Callback(Database db, DBResultSet results, const char[] error, any data)
{
InsertMigration(data);
Expand Down
8 changes: 4 additions & 4 deletions addons/sourcemod/scripting/shavit-core.sp
Original file line number Diff line number Diff line change
Expand Up @@ -2807,14 +2807,14 @@ public void OnClientAuthorized(int client, const char[] auth)
if (gI_Driver == Driver_mysql)
{
FormatEx(sQuery, 512,
"INSERT INTO %susers (auth, name, ip, lastlogin) VALUES (%d, '%s', %d, %d) ON DUPLICATE KEY UPDATE name = '%s', ip = %d, lastlogin = %d;",
gS_MySQLPrefix, iSteamID, sEscapedName, iIPAddress, iTime, sEscapedName, iIPAddress, iTime);
"INSERT INTO %susers (auth, name, ip, lastlogin, firstlogin) VALUES (%d, '%s', %d, %d, %d) ON DUPLICATE KEY UPDATE name = '%s', ip = %d, lastlogin = %d;",
gS_MySQLPrefix, iSteamID, sEscapedName, iIPAddress, iTime, iTime, sEscapedName, iIPAddress, iTime);
}
else // postgresql & sqlite
{
FormatEx(sQuery, 512,
"INSERT INTO %susers (auth, name, ip, lastlogin) VALUES (%d, '%s', %d, %d) ON CONFLICT(auth) DO UPDATE SET name = '%s', ip = %d, lastlogin = %d;",
gS_MySQLPrefix, iSteamID, sEscapedName, iIPAddress, iTime, sEscapedName, iIPAddress, iTime);
"INSERT INTO %susers (auth, name, ip, lastlogin, firstlogin) VALUES (%d, '%s', %d, %d, %d) ON CONFLICT(auth) DO UPDATE SET name = '%s', ip = %d, lastlogin = %d;",
gS_MySQLPrefix, iSteamID, sEscapedName, iIPAddress, iTime, iTime, sEscapedName, iIPAddress, iTime);
}

QueryLog(gH_SQL, SQL_InsertUser_Callback, sQuery, GetClientSerial(client));
Expand Down
21 changes: 13 additions & 8 deletions addons/sourcemod/scripting/shavit-stats.sp
Original file line number Diff line number Diff line change
Expand Up @@ -890,9 +890,9 @@ Action OpenStatsMenu_Main(int steamid, int style, DataPack data)
char sQuery[2048];

FormatEx(sQuery, sizeof(sQuery),
"SELECT 0, points, lastlogin, ip, playtime, name FROM %susers WHERE auth = %d\n" ...
"UNION ALL SELECT 1, SUM(playtime), 0, 0, 0, '' FROM %sstyleplaytime WHERE auth = %d AND style = %d\n" ...
"UNION ALL SELECT 2, COUNT(*), 0, 0, 0, '' FROM %susers u1\n" ...
"SELECT 0, points, lastlogin, firstlogin, ip, playtime, name FROM %susers WHERE auth = %d\n" ...
"UNION ALL SELECT 1, SUM(playtime), 0, 0, 0, 0, '' FROM %sstyleplaytime WHERE auth = %d AND style = %d\n" ...
"UNION ALL SELECT 2, COUNT(*), 0, 0, 0, 0, '' FROM %susers u1\n" ...
" JOIN (SELECT points FROM %susers WHERE auth = %d) u2\n" ...
" WHERE u1.points >= u2.points",
gS_MySQLPrefix, steamid,
Expand Down Expand Up @@ -960,6 +960,7 @@ public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[]

float fPoints;
char sLastLogin[32];
char sFirstLogin[32];
char sCountry[64];
char sPlaytime[16];

Expand Down Expand Up @@ -989,7 +990,11 @@ public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[]
FormatTime(sLastLogin, 32, "%Y-%m-%d %H:%M:%S", iLastLogin);
Format(sLastLogin, 32, "%T: %s", "LastLogin", client, (iLastLogin != -1)? sLastLogin:"N/A");

int iIPAddress = results.FetchInt(3);
int iFirstLogin = results.FetchInt(3);
FormatTime(sFirstLogin, 32, "%Y-%m-%d %H:%M:%S", iFirstLogin);
Format(sFirstLogin, 32, "%T: %s", "FirstLogin", client, (iFirstLogin != -1)? sFirstLogin:"N/A");

int iIPAddress = results.FetchInt(4);
char sIPAddress[32];
IPAddressToString(iIPAddress, sIPAddress, 32);

Expand All @@ -998,10 +1003,10 @@ public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[]
sCountry = "Local Area Network";
}

float fPlaytime = results.FetchFloat(4);
float fPlaytime = results.FetchFloat(5);
FormatSeconds(fPlaytime, sPlaytime, sizeof(sPlaytime), false, true, true);

results.FetchString(5, gS_TargetName[client], MAX_NAME_LENGTH);
results.FetchString(6, gS_TargetName[client], MAX_NAME_LENGTH);
ReplaceString(gS_TargetName[client], MAX_NAME_LENGTH, "#", "?");
}
else if (type == 1)
Expand Down Expand Up @@ -1056,8 +1061,8 @@ public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[]
}

Menu menu = new Menu(MenuHandler_ProfileHandler);
menu.SetTitle("%s's %T. [U:1:%u]\n%T: %s\n%s\n%s\n%T: %s\n",
gS_TargetName[client], "Profile", client, gI_TargetSteamID[client], "Country", client, sCountry, sLastLogin,
menu.SetTitle("%s's %T. [U:1:%u]\n%T: %s\n%s\n%s\n%s\n%T: %s\n",
gS_TargetName[client], "Profile", client, gI_TargetSteamID[client], "Country", client, sCountry, sFirstLogin, sLastLogin,
sRankingString, "Playtime", client, sPlaytime);

int[] styles = new int[gI_Styles];
Expand Down
4 changes: 4 additions & 0 deletions addons/sourcemod/translations/shavit-stats.phrases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
{
"en" "Last Login"
}
"FirstLogin"
{
"en" "First Login"
}
"MapCompletions"
{
"en" "Map completions"
Expand Down