Add FirstLogin to database and profile (#1234)
Some checks failed
Compile / Build SM ${{ matrix.sm-version }} (1.12) (push) Has been cancelled
Compile / Release (push) Has been cancelled

fix FirstLogin query for sqlite

fix statsmenu query oopsie teehee :3

sql-create-tables-and-migrations.sp - fix queries for sqlite

Simplify firstlogin column initialization
This commit is contained in:
olivia 2025-04-14 10:52:36 -07:00 committed by rtldg
parent 354c2445c2
commit 3d0cd96319
4 changed files with 40 additions and 14 deletions

View File

@ -53,6 +53,7 @@ enum
Migration_DeprecateExactTimeInt,
Migration_AddPlayertimesAuthFK,
Migration_FixSQLiteMapzonesROWID,
Migration_AddUsersFirstLogin,
MIGRATIONS_END
};
@ -87,6 +88,7 @@ char gS_MigrationNames[][] = {
"DeprecateExactTimeInt",
"AddPlayertimesAuthFK",
"FixSQLiteMapzonesROWID",
"AddUsersFirstLogin",
};
static Database gH_SQL;
@ -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);
}
@ -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();
}
}
@ -686,6 +689,20 @@ 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];
FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET firstlogin = lastlogin WHERE lastlogin > 0;", 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);

View File

@ -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));

View File

@ -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,
@ -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];
@ -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);
@ -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)
@ -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];

View File

@ -74,6 +74,10 @@
{
"en" "Last Login"
}
"FirstLogin"
{
"en" "First Login"
}
"MapCompletions"
{
"en" "Map completions"