Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/ST-Events/Players.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo i

// To-do: hardcoded Style value
// Load MapTimes for the player's PB and their Checkpoints
playerList[player.UserId ?? 0].Stats.LoadMapTimesData(playerList[player.UserId ?? 0], DB); // Will reload PB and Checkpoints for the player for all styles
playerList[player.UserId ?? 0].Stats.LoadCheckpointsData(DB); // To-do: This really should go inside `LoadMapTimesData` imo cuz here we hardcoding load for Style 0
Task.Run(async () => await playerList[player.UserId ?? 0].Stats.LoadMapTimesData(playerList[player.UserId ?? 0], DB)); // Will reload PB and Checkpoints for the player for all styles
Task.Run(async () => await playerList[player.UserId ?? 0].Stats.LoadCheckpointsData(DB)); // To-do: This really should go inside `LoadMapTimesData` imo cuz here we hardcoding load for Style 0

// Print join messages
Server.PrintToChatAll($"{PluginPrefix} {ChatColors.Green}{player.PlayerName}{ChatColors.Default} has connected from {ChatColors.Lime}{playerList[player.UserId ?? 0].Profile.Country}{ChatColors.Default}.");
Expand Down
4 changes: 2 additions & 2 deletions src/ST-Events/TriggerStartTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler)

// Add entry in DB for the run
player.Stats.ThisRun.SaveMapTime(player, DB); // Save the MapTime PB data
player.Stats.LoadMapTimesData(player, DB); // Load the MapTime PB data again (will refresh the MapTime ID for the Checkpoints query)
Task.Run(async () => await player.Stats.LoadMapTimesData(player, DB)); // Load the MapTime PB data again (will refresh the MapTime ID for the Checkpoints query)
player.Stats.ThisRun.SaveCurrentRunCheckpoints(player, DB); // Save this run's checkpoints
player.Stats.LoadCheckpointsData(DB); // Reload checkpoints for the run - we should really have this in `SaveMapTime` as well but we don't re-load PB data inside there so we need to do it here
Task.Run(async () => await player.Stats.LoadCheckpointsData(DB)); // Reload checkpoints for the run - we should really have this in `SaveMapTime` as well but we don't re-load PB data inside there so we need to do it here
CurrentMap.GetMapRecordAndTotals(DB); // Reload the Map record and totals for the HUD
}

Expand Down
192 changes: 99 additions & 93 deletions src/ST-Player/PlayerStats/PlayerStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,123 +26,129 @@ public PlayerStats()
/// `Checkpoints` are loaded separately because inside the while loop we cannot run queries.
/// This can populate all the `style` stats the player has for the map - currently only 1 style is supported
/// </summary>
public void LoadMapTimesData(Player player, TimerDatabase DB, int playerId = 0, int mapId = 0)
public async Task LoadMapTimesData(Player player, TimerDatabase DB, int playerId = 0, int mapId = 0)
{
Task<MySqlDataReader> dbTask2 = DB.Query($"SELECT mainquery.*, (SELECT COUNT(*) FROM `MapTimes` AS subquery " +
$"WHERE subquery.`map_id` = mainquery.`map_id` AND subquery.`style` = mainquery.`style` " +
$"AND subquery.`run_time` <= mainquery.`run_time`) AS `rank` FROM `MapTimes` AS mainquery " +
$"WHERE mainquery.`player_id` = {player.Profile.ID} AND mainquery.`map_id` = {player.CurrMap.ID}; ");
MySqlDataReader playerStats = dbTask2.Result;
int style = 0; // To-do: implement styles
if (!playerStats.HasRows)
await Task.Run(async () =>
{
Console.WriteLine($"CS2 Surf DEBUG >> internal class PlayerStats -> LoadMapTimesData -> No MapTimes data found for Player.");
}
else
{
while (playerStats.Read())
MySqlDataReader playerStats = await DB.Query($"SELECT mainquery.*, (SELECT COUNT(*) FROM `MapTimes` AS subquery " +
$"WHERE subquery.`map_id` = mainquery.`map_id` AND subquery.`style` = mainquery.`style` " +
$"AND subquery.`run_time` <= mainquery.`run_time`) AS `rank` FROM `MapTimes` AS mainquery " +
$"WHERE mainquery.`player_id` = {player.Profile.ID} AND mainquery.`map_id` = {player.CurrMap.ID}; ");
int style = 0; // To-do: implement styles
if (!playerStats.HasRows)
{
// Load data into PersonalBest object
// style = playerStats.GetInt32("style"); // Uncomment when style is implemented
PB[style].ID = playerStats.GetInt32("id");
PB[style].StartVelX = (float)playerStats.GetDouble("start_vel_x");
PB[style].StartVelY = (float)playerStats.GetDouble("start_vel_y");
PB[style].StartVelZ = (float)playerStats.GetDouble("start_vel_z");
PB[style].EndVelX = (float)playerStats.GetDouble("end_vel_x");
PB[style].EndVelY = (float)playerStats.GetDouble("end_vel_y");
PB[style].EndVelZ = (float)playerStats.GetDouble("end_vel_z");
PB[style].Ticks = playerStats.GetInt32("run_time");
PB[style].RunDate = playerStats.GetInt32("run_date");
PB[style].Rank = playerStats.GetInt32("rank");

Console.WriteLine($"============== CS2 Surf DEBUG >> LoadMapTimesData -> PlayerID: {player.Profile.ID} | Rank: {PB[style].Rank} | ID: {PB[style].ID} | RunTime: {PB[style].Ticks} | SVX: {PB[style].StartVelX} | SVY: {PB[style].StartVelY} | SVZ: {PB[style].StartVelZ} | EVX: {PB[style].EndVelX} | EVY: {PB[style].EndVelY} | EVZ: {PB[style].EndVelZ} | Run Date (UNIX): {PB[style].RunDate}");
#if DEBUG
Console.WriteLine($"CS2 Surf DEBUG >> internal class PlayerStats -> LoadMapTimesData -> PlayerStats.PB (ID {PB[style].ID}) loaded from DB.");
#endif
Console.WriteLine($"CS2 Surf DEBUG >> internal class PlayerStats -> LoadMapTimesData -> No MapTimes data found for Player.");
}
else
{
while (playerStats.Read())
{
// Load data into PersonalBest object
// style = playerStats.GetInt32("style"); // Uncomment when style is implemented
PB[style].ID = playerStats.GetInt32("id");
PB[style].StartVelX = (float)playerStats.GetDouble("start_vel_x");
PB[style].StartVelY = (float)playerStats.GetDouble("start_vel_y");
PB[style].StartVelZ = (float)playerStats.GetDouble("start_vel_z");
PB[style].EndVelX = (float)playerStats.GetDouble("end_vel_x");
PB[style].EndVelY = (float)playerStats.GetDouble("end_vel_y");
PB[style].EndVelZ = (float)playerStats.GetDouble("end_vel_z");
PB[style].Ticks = playerStats.GetInt32("run_time");
PB[style].RunDate = playerStats.GetInt32("run_date");
PB[style].Rank = playerStats.GetInt32("rank");

Console.WriteLine($"============== CS2 Surf DEBUG >> LoadMapTimesData -> PlayerID: {player.Profile.ID} | Rank: {PB[style].Rank} | ID: {PB[style].ID} | RunTime: {PB[style].Ticks} | SVX: {PB[style].StartVelX} | SVY: {PB[style].StartVelY} | SVZ: {PB[style].StartVelZ} | EVX: {PB[style].EndVelX} | EVY: {PB[style].EndVelY} | EVZ: {PB[style].EndVelZ} | Run Date (UNIX): {PB[style].RunDate}");
#if DEBUG
Console.WriteLine($"CS2 Surf DEBUG >> internal class PlayerStats -> LoadMapTimesData -> PlayerStats.PB (ID {PB[style].ID}) loaded from DB.");
#endif
}
}
}
playerStats.Close();

playerStats.Close();
});
}

/// <summary>
/// Executes the DB query to get all the checkpoints and store them in the Checkpoint dictionary
/// </summary>
public void LoadCheckpointsData(TimerDatabase DB)
public async Task LoadCheckpointsData(TimerDatabase DB)
{
Task<MySqlDataReader> dbTask = DB.Query($"SELECT * FROM `Checkpoints` WHERE `maptime_id` = {PB[0].ID};");
MySqlDataReader results = dbTask.Result;
if (PB[0] == null)
{
#if DEBUG
Console.WriteLine("CS2 Surf ERROR >> internal class PlayerStats -> LoadCheckpointsData -> PersonalBest object is null.");
#endif

results.Close();
return;
}
await Task.Run(async () =>
{
MySqlDataReader results = await DB.Query($"SELECT * FROM `Checkpoints` WHERE `maptime_id` = {PB[0].ID};");
if (PB[0] == null)
{
#if DEBUG
Console.WriteLine("CS2 Surf ERROR >> internal class PlayerStats -> LoadCheckpointsData -> PersonalBest object is null.");
#endif

if (PB[0].Checkpoint == null)
{
#if DEBUG
Console.WriteLine($"CS2 Surf DEBUG >> internal class PlayerStats -> LoadCheckpointsData -> PB Checkpoints list is not initialized.");
#endif
results.Close();
return;
}

PB[0].Checkpoint = new Dictionary<int, Checkpoint>(); // Initialize if null
}
if (PB[0].Checkpoint == null)
{
#if DEBUG
Console.WriteLine($"CS2 Surf DEBUG >> internal class PlayerStats -> LoadCheckpointsData -> PB Checkpoints list is not initialized.");
#endif

#if DEBUG
Console.WriteLine($"this.Checkpoint.Count {PB[0].Checkpoint.Count} ");
Console.WriteLine($"this.ID {PB[0].ID} ");
Console.WriteLine($"this.Ticks {PB[0].Ticks} ");
Console.WriteLine($"this.RunDate {PB[0].RunDate} ");
#endif
PB[0].Checkpoint = new Dictionary<int, Checkpoint>(); // Initialize if null
}

if (!results.HasRows)
{
#if DEBUG
Console.WriteLine($"CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> No checkpoints found for this mapTimeId {PB[0].ID}.");
Console.WriteLine($"this.Checkpoint.Count {PB[0].Checkpoint.Count} ");
Console.WriteLine($"this.ID {PB[0].ID} ");
Console.WriteLine($"this.Ticks {PB[0].Ticks} ");
Console.WriteLine($"this.RunDate {PB[0].RunDate} ");
#endif

results.Close();
return;
}
if (!results.HasRows)
{
#if DEBUG
Console.WriteLine($"CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> No checkpoints found for this mapTimeId {PB[0].ID}.");
#endif

#if DEBUG
Console.WriteLine($"======== CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> Checkpoints found for this mapTimeId");
#endif
results.Close();
return;
}

while (results.Read())
{
#if DEBUG
Console.WriteLine($"cp {results.GetInt32("cp")} ");
Console.WriteLine($"run_time {results.GetFloat("run_time")} ");
Console.WriteLine($"sVelX {results.GetFloat("start_vel_x")} ");
Console.WriteLine($"sVelY {results.GetFloat("start_vel_y")} ");
Console.WriteLine($"======== CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> Checkpoints found for this mapTimeId");
#endif

Checkpoint cp = new(results.GetInt32("cp"),
results.GetInt32("run_time"), // To-do: what type of value we use here? DB uses DECIMAL but `.Tick` is int???
results.GetFloat("start_vel_x"),
results.GetFloat("start_vel_y"),
results.GetFloat("start_vel_z"),
results.GetFloat("end_vel_x"),
results.GetFloat("end_vel_y"),
results.GetFloat("end_vel_z"),
results.GetFloat("end_touch"),
results.GetInt32("attempts"));
cp.ID = results.GetInt32("cp");
// To-do: cp.ID = calculate Rank # from DB

PB[0].Checkpoint[cp.CP] = cp;
while (results.Read())
{
#if DEBUG
Console.WriteLine($"cp {results.GetInt32("cp")} ");
Console.WriteLine($"run_time {results.GetFloat("run_time")} ");
Console.WriteLine($"sVelX {results.GetFloat("start_vel_x")} ");
Console.WriteLine($"sVelY {results.GetFloat("start_vel_y")} ");
#endif

Checkpoint cp = new(results.GetInt32("cp"),
results.GetInt32("run_time"), // To-do: what type of value we use here? DB uses DECIMAL but `.Tick` is int???
results.GetFloat("start_vel_x"),
results.GetFloat("start_vel_y"),
results.GetFloat("start_vel_z"),
results.GetFloat("end_vel_x"),
results.GetFloat("end_vel_y"),
results.GetFloat("end_vel_z"),
results.GetFloat("end_touch"),
results.GetInt32("attempts"));
cp.ID = results.GetInt32("cp");
// To-do: cp.ID = calculate Rank # from DB

PB[0].Checkpoint[cp.CP] = cp;

#if DEBUG
Console.WriteLine($"======= CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> Loaded CP {cp.CP} with RunTime {cp.Ticks}.");
#endif
}

results.Close();

#if DEBUG
Console.WriteLine($"======= CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> Loaded CP {cp.CP} with RunTime {cp.Ticks}.");
Console.WriteLine($"======= CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> Checkpoints loaded from DB. Count: {PB[0].Checkpoint.Count}");
#endif
}
results.Close();

#if DEBUG
Console.WriteLine($"======= CS2 Surf DEBUG >> internal class Checkpoint : PersonalBest -> LoadCheckpointsData -> Checkpoints loaded from DB. Count: {PB[0].Checkpoint.Count}");
#endif
});
}
}