From 7929056db92b9155c803b6fe84b812d0a9626798 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:00:49 +0200 Subject: [PATCH 01/11] update time formatting - support hours --- src/ST-Player/PlayerHUD.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index a92978c..86a87f6 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -32,7 +32,17 @@ public string FormatTime(int ticks) // https://github.com/DEAFPS/SharpTimer/blob { TimeSpan time = TimeSpan.FromSeconds(ticks / 64.0); int millis = (int)(ticks % 64 * (1000.0 / 64.0)); - return $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + + // Handle hours in times + if (time.TotalHours < 1) + return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + + // No leading 0s + string secondsFormat = time.TotalSeconds < 10 ? "D1" : "D2"; + string minutesFormat = time.TotalMinutes < 10 ? "D1" : "D2"; + + // Don't show 00: in times + return time.TotalMinutes < 1 ? $"{time.Seconds.ToString(secondsFormat)}.{millis:D3}" : $"{time.Minutes.ToString(minutesFormat)}:{time.Seconds:D2}.{millis:D3}"; } public void Display() @@ -51,14 +61,14 @@ public void Display() string timerModule = FormatHUDElementHTML("", FormatTime(_player.Timer.Ticks), timerColor); // Velocity Module - To-do: Make velocity module configurable (XY or XYZ velocity) - float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X - + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X + + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + _player.Controller.PlayerPawn.Value!.AbsVelocity.Z * _player.Controller.PlayerPawn.Value!.AbsVelocity.Z); string velocityModule = FormatHUDElementHTML("Speed", velocity.ToString("000"), "#79d1ed") + " u/s"; // Rank Module string rankModule = FormatHUDElementHTML("Rank", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // PB & WR Modules - string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0,0] > 0 ? FormatTime(_player.Stats.PB[0,0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats + string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0, 0] > 0 ? FormatTime(_player.Stats.PB[0, 0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats string wrModule = FormatHUDElementHTML("WR", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // Build HUD From cb1a50d82a530cca503ede0db1bd9a85aaee1bb7 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:24:14 +0200 Subject: [PATCH 02/11] Revert "update time formatting - support hours" This reverts commit 7929056db92b9155c803b6fe84b812d0a9626798. --- src/ST-Player/PlayerHUD.cs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index 86a87f6..a92978c 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -32,17 +32,7 @@ public string FormatTime(int ticks) // https://github.com/DEAFPS/SharpTimer/blob { TimeSpan time = TimeSpan.FromSeconds(ticks / 64.0); int millis = (int)(ticks % 64 * (1000.0 / 64.0)); - - // Handle hours in times - if (time.TotalHours < 1) - return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; - - // No leading 0s - string secondsFormat = time.TotalSeconds < 10 ? "D1" : "D2"; - string minutesFormat = time.TotalMinutes < 10 ? "D1" : "D2"; - - // Don't show 00: in times - return time.TotalMinutes < 1 ? $"{time.Seconds.ToString(secondsFormat)}.{millis:D3}" : $"{time.Minutes.ToString(minutesFormat)}:{time.Seconds:D2}.{millis:D3}"; + return $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; } public void Display() @@ -61,14 +51,14 @@ public void Display() string timerModule = FormatHUDElementHTML("", FormatTime(_player.Timer.Ticks), timerColor); // Velocity Module - To-do: Make velocity module configurable (XY or XYZ velocity) - float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X - + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X + + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + _player.Controller.PlayerPawn.Value!.AbsVelocity.Z * _player.Controller.PlayerPawn.Value!.AbsVelocity.Z); string velocityModule = FormatHUDElementHTML("Speed", velocity.ToString("000"), "#79d1ed") + " u/s"; // Rank Module string rankModule = FormatHUDElementHTML("Rank", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // PB & WR Modules - string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0, 0] > 0 ? FormatTime(_player.Stats.PB[0, 0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats + string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0,0] > 0 ? FormatTime(_player.Stats.PB[0,0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats string wrModule = FormatHUDElementHTML("WR", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // Build HUD From ad56633ece69af0117c0ca6850b5365102ec508b Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:27:37 +0200 Subject: [PATCH 03/11] time formatting - support hours --- src/ST-Player/PlayerHUD.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index a92978c..1a2d40d 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -32,7 +32,17 @@ public string FormatTime(int ticks) // https://github.com/DEAFPS/SharpTimer/blob { TimeSpan time = TimeSpan.FromSeconds(ticks / 64.0); int millis = (int)(ticks % 64 * (1000.0 / 64.0)); - return $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + + // Handle hours in times + if (time.TotalHours >= 1) + return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + + // No leading 0s + string secondsFormat = time.TotalSeconds < 10 ? "D1" : "D2"; + string minutesFormat = time.TotalMinutes < 10 ? "D1" : "D2"; + + // Don't show 00: in times + return time.TotalMinutes < 1 ? $"{time.Seconds.ToString(secondsFormat)}.{millis:D3}" : $"{time.Minutes.ToString(minutesFormat)}:{time.Seconds:D2}.{millis:D3}"; } public void Display() From 20b84a5a388c81b8f08b43d4206dfcee1571cab1 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:25:28 +0200 Subject: [PATCH 04/11] pre speed for stages --- src/ST-Events/TriggerEndTouch.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ST-Events/TriggerEndTouch.cs b/src/ST-Events/TriggerEndTouch.cs index e36280a..866c12d 100644 --- a/src/ST-Events/TriggerEndTouch.cs +++ b/src/ST-Events/TriggerEndTouch.cs @@ -54,6 +54,12 @@ internal HookResult OnTriggerEndTouch(DynamicHook handler) #if DEBUG player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_{ChatColors.LightRed}EndTouchFunc{ChatColors.Default} -> {ChatColors.Yellow}Stage {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} Start Zone"); #endif + + // Show Prespeed for stages - will be enabled/disabled by the user? + float velocity = (float)Math.Sqrt(player.Controller.PlayerPawn.Value!.AbsVelocity.X * player.Controller.PlayerPawn.Value!.AbsVelocity.X + + player.Controller.PlayerPawn.Value!.AbsVelocity.Y * player.Controller.PlayerPawn.Value!.AbsVelocity.Y + + player.Controller.PlayerPawn.Value!.AbsVelocity.Z * player.Controller.PlayerPawn.Value!.AbsVelocity.Z); + player.Controller.PrintToCenter($"Stage {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} - Prespeed: {velocity.ToString("0")} u/s"); } } From 1d89780b31ae4ed9eb94a711c2205b3e7eba1cca Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:53:17 +0200 Subject: [PATCH 05/11] color country --- src/ST-Events/Players.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ST-Events/Players.cs b/src/ST-Events/Players.cs index 011cbaf..0133785 100644 --- a/src/ST-Events/Players.cs +++ b/src/ST-Events/Players.cs @@ -104,7 +104,7 @@ public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo i Profile); // Print join messages - Server.PrintToChatAll($"{PluginPrefix} {ChatColors.Green}{player.PlayerName}{ChatColors.Default} has connected from {playerList[player.UserId ?? 0].Profile.Country}."); + Server.PrintToChatAll($"{PluginPrefix} {ChatColors.Green}{player.PlayerName}{ChatColors.Default} has connected from {ChatColors.Lime}{playerList[player.UserId ?? 0].Profile.Country}{ChatColors.Default}."); Console.WriteLine($"[CS2 Surf] {player.PlayerName} has connected from {playerList[player.UserId ?? 0].Profile.Country}."); return HookResult.Continue; } From 4faf972e495015e3a7bed3832002742f84cc8811 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Tue, 19 Dec 2023 00:04:22 +0200 Subject: [PATCH 06/11] CP prints - mostly hardcoded - store cps for run --- src/ST-Events/TriggerStartTouch.cs | 71 +++++++++++++++++++++++++++++- src/ST-Player/PlayerTimer.cs | 7 +++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/ST-Events/TriggerStartTouch.cs b/src/ST-Events/TriggerStartTouch.cs index dee74ba..54c84bc 100644 --- a/src/ST-Events/TriggerStartTouch.cs +++ b/src/ST-Events/TriggerStartTouch.cs @@ -2,6 +2,7 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using System.Text.Json; namespace SurfTimer; @@ -27,6 +28,15 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_StartTouchFunc -> {trigger.DesignerName} -> {trigger.Entity!.Name}"); #endif + // Get the velocity of the player - we will be using this values to compare and write to DB + float velocity = (float)Math.Sqrt(player.Controller.PlayerPawn.Value!.AbsVelocity.X * player.Controller.PlayerPawn.Value!.AbsVelocity.X + + player.Controller.PlayerPawn.Value!.AbsVelocity.Y * player.Controller.PlayerPawn.Value!.AbsVelocity.Y + + player.Controller.PlayerPawn.Value!.AbsVelocity.Z * player.Controller.PlayerPawn.Value!.AbsVelocity.Z); + float velocity_x = player.Controller.PlayerPawn.Value!.AbsVelocity.X; + float velocity_y = player.Controller.PlayerPawn.Value!.AbsVelocity.Y; + float velocity_z = player.Controller.PlayerPawn.Value!.AbsVelocity.Z; + + if (trigger.Entity!.Name != null) { // Map end zones -- hook into map_end @@ -39,7 +49,26 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) if (player.Stats.PB[0,0] == 0 || player.Timer.Ticks < player.Stats.PB[0,0]) player.Stats.PB[0,0] = player.Timer.Ticks; player.Controller.PrintToChat($"{PluginPrefix} You finished the map in {player.HUD.FormatTime(player.Stats.PB[0,0])}!"); - // player.Timer.Reset(); + + foreach (var item in player.Timer.CurrentRunCheckpoints) + { + int cp = item.GetProperty("cp").GetInt32(); + string time = item.GetProperty("time").GetString(); + int ticks = item.GetProperty("ticks").GetInt32(); + double speed = item.GetProperty("speed").GetDouble(); + double velX = item.GetProperty("velX").GetDouble(); + double velY = item.GetProperty("velY").GetDouble(); + double velZ = item.GetProperty("velZ").GetDouble(); + + Console.WriteLine($"CP: {cp} | Time: {time} | Ticks: {ticks} | Speed: {speed} | VelX: {velX} | VelY: {velY} | VelZ: {velZ}"); + + // Write new CPs to database + // Transactions? + // Task newPbTask = DB.Write($"INSERT INTO `Checkpoints` (`maptime_id`, `cp`, `runtime`, `velX`, `velY`, `velZ`) VALUES ('0', {cp}, '{ticks}', {velX}, {velY}, {velZ});"); + // int newPbTaskRows = newPbTask.Result; + // if (newPbTaskRows != 1) + // throw new Exception($"CS2 Surf ERROR >> Inserting Checkpoints."); + } } #if DEBUG @@ -66,7 +95,25 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) int stage = Int32.Parse(Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value) - 1; player.Timer.Stage = stage; - // To-do: checkpoint functionality because stages = checkpoints + // To-do: checkpoint functionality because stages = checkpoints when in a run on a Staged map + // To-do: This triggers more than once at random :monkaHmm: + // This should patch up re-triggering *player.Timer.CurrentRunCheckpoints.Count < stage* + if (player.Timer.IsRunning && !player.Timer.StageMode && player.Timer.CurrentRunCheckpoints.Count < stage) + { + player.Controller.PrintToChat( + $"{PluginPrefix} CP [{ChatColors.Yellow}{stage}{ChatColors.Default}]: " + + $"{ChatColors.Yellow}{player.HUD.FormatTime(player.Timer.Ticks)}{ChatColors.Default} " + + $"{ChatColors.Yellow}({velocity.ToString("0")}){ChatColors.Default} " + + $"[PB: {ChatColors.Green}-00:00.000{ChatColors.Default} " + + $"{ChatColors.Red}(-1234){ChatColors.Default} | " + + $"WR: {ChatColors.Red}+00:00.000{ChatColors.Default} " + + $"{ChatColors.Green}(+1234){ChatColors.Default}]"); + + // .... store in an array to INSERT/UPDATE in DB at the end of run? + string jsonString = $"{{ \"cp\": {stage}, \"time\": \"{player.HUD.FormatTime(player.Timer.Ticks)}\", \"ticks\": {player.Timer.Ticks}, \"speed\": {velocity}, \"velX\": {velocity_x}, \"velY\": {velocity_y}, \"velZ\": {velocity_z} }}"; + JsonElement currRunCps = JsonDocument.Parse(jsonString).RootElement; + player.Timer.CurrentRunCheckpoints.Add(currRunCps); + } #if DEBUG player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_{ChatColors.Lime}StartTouchFunc{ChatColors.Default} -> {ChatColors.Yellow}Stage {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} Start Zone"); @@ -76,7 +123,27 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) // Map checkpoint zones -- hook into map_(c)heck(p)oint# else if (Regex.Match(trigger.Entity.Name, "^map_c(p[1-9][0-9]?|heckpoint[1-9][0-9]?)$").Success) { + int checkpoint = Int32.Parse(Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value) - 1; + player.Timer.Checkpoint = checkpoint; + // To-do: checkpoint functionality + if (player.Timer.IsRunning && !player.Timer.StageMode && player.Timer.CurrentRunCheckpoints.Count < checkpoint) + { + player.Controller.PrintToChat( + $"{PluginPrefix} CP [{ChatColors.Yellow}{checkpoint}{ChatColors.Default}]: " + + $"{ChatColors.Yellow}{player.HUD.FormatTime(player.Timer.Ticks)}{ChatColors.Default} " + + $"{ChatColors.Yellow}({velocity.ToString("0")}){ChatColors.Default} " + + $"[PB: {ChatColors.Green}-00:00.000{ChatColors.Default} " + + $"{ChatColors.Red}(-1234){ChatColors.Default} | " + + $"WR: {ChatColors.Red}+00:00.000{ChatColors.Default} " + + $"{ChatColors.Green}(+1234){ChatColors.Default}]"); + + // .... store in an array to INSERT/UPDATE in DB at the end of run? + string jsonString = $"{{ \"cp\": {checkpoint}, \"time\": \"{player.HUD.FormatTime(player.Timer.Ticks)}\", \"ticks\": {player.Timer.Ticks}, \"speed\": {velocity}, \"velX\": {velocity_x}, \"velY\": {velocity_y}, \"velZ\": {velocity_z} }}"; + JsonElement currRunCps = JsonDocument.Parse(jsonString).RootElement; + player.Timer.CurrentRunCheckpoints.Add(currRunCps); + // .... store in an array to INSERT/UPDATE in DB at the end of run? + } #if DEBUG player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_{ChatColors.Lime}StartTouchFunc{ChatColors.Default} -> {ChatColors.LightBlue}Checkpoint {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} Zone"); diff --git a/src/ST-Player/PlayerTimer.cs b/src/ST-Player/PlayerTimer.cs index 97df4f4..a4dc6ca 100644 --- a/src/ST-Player/PlayerTimer.cs +++ b/src/ST-Player/PlayerTimer.cs @@ -1,3 +1,6 @@ +using System.Runtime.InteropServices; +using System.Text.Json; + namespace SurfTimer; internal class PlayerTimer @@ -13,6 +16,8 @@ internal class PlayerTimer // Tracking public int Stage {get; set;} = 0; // Current stage tracker + public int Checkpoint {get; set;} = 0; // Current checkpoint tracker + public List CurrentRunCheckpoints { get; set; } = new List(); // Current run cps list public int Bonus {get; set;} = 0; // Current bonus tracker - To-do: bonus implementation // public int Style = 0; // To-do: style implementation @@ -25,8 +30,10 @@ public void Reset() this.Stop(); this.Ticks = 0; this.Stage = 0; + this.Checkpoint = 0; this.Paused = false; this.PracticeMode = false; + this.CurrentRunCheckpoints.Clear(); } public void Pause() From 31b062cf94e2b2adedf48e958c989f9eb10a83d7 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:23:19 +0200 Subject: [PATCH 07/11] 3 types of time formatting --- src/ST-Player/PlayerHUD.cs | 28 +++++++++++++++++++++++----- src/ST-Player/PlayerTimer.cs | 26 +++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index a92978c..0ce6755 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -28,11 +28,29 @@ private string FormatHUDElementHTML(string title, string body, string color, str } } - public string FormatTime(int ticks) // https://github.com/DEAFPS/SharpTimer/blob/e4ef24fff29a33c36722d23961355742d507441f/Utils.cs#L38 + /// + /// Formats the given time in ticks into a readable time string. + /// Unless specified differently, the default formatting will be `Verbose`. + /// Check for all formatting types. + /// + public string FormatTime(int ticks, PlayerTimer.TimeFormatStyle style = PlayerTimer.TimeFormatStyle.Verbose) { TimeSpan time = TimeSpan.FromSeconds(ticks / 64.0); int millis = (int)(ticks % 64 * (1000.0 / 64.0)); - return $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + + switch (style) + { + case PlayerTimer.TimeFormatStyle.Compact: + return time.TotalMinutes < 1 + ? $"{time.Seconds:D2}.{millis:D3}" + : $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + case PlayerTimer.TimeFormatStyle.Full: + return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + case PlayerTimer.TimeFormatStyle.Verbose: + return $"{time.Hours}h {time.Minutes}m {time.Seconds}s {millis}ms"; + default: + throw new ArgumentException("Invalid time format style"); + } } public void Display() @@ -51,14 +69,14 @@ public void Display() string timerModule = FormatHUDElementHTML("", FormatTime(_player.Timer.Ticks), timerColor); // Velocity Module - To-do: Make velocity module configurable (XY or XYZ velocity) - float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X - + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X + + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + _player.Controller.PlayerPawn.Value!.AbsVelocity.Z * _player.Controller.PlayerPawn.Value!.AbsVelocity.Z); string velocityModule = FormatHUDElementHTML("Speed", velocity.ToString("000"), "#79d1ed") + " u/s"; // Rank Module string rankModule = FormatHUDElementHTML("Rank", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // PB & WR Modules - string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0,0] > 0 ? FormatTime(_player.Stats.PB[0,0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats + string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0, 0] > 0 ? FormatTime(_player.Stats.PB[0, 0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats string wrModule = FormatHUDElementHTML("WR", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // Build HUD diff --git a/src/ST-Player/PlayerTimer.cs b/src/ST-Player/PlayerTimer.cs index 97df4f4..f153908 100644 --- a/src/ST-Player/PlayerTimer.cs +++ b/src/ST-Player/PlayerTimer.cs @@ -3,21 +3,29 @@ namespace SurfTimer; internal class PlayerTimer { // Status - public bool Enabled {get; set;} = true; // Enable toggle for entire timer - public bool Paused {get; set;} = false; // Pause toggle for timer - public bool IsRunning {get; set;} = false; // Is the timer currently running? + public bool Enabled { get; set; } = true; // Enable toggle for entire timer + public bool Paused { get; set; } = false; // Pause toggle for timer + public bool IsRunning { get; set; } = false; // Is the timer currently running? // Modes - public bool PracticeMode {get; set;} = false; // Practice mode toggle - public bool StageMode {get; set;} = false; // Stage mode toggle + public bool PracticeMode { get; set; } = false; // Practice mode toggle + public bool StageMode { get; set; } = false; // Stage mode toggle // Tracking - public int Stage {get; set;} = 0; // Current stage tracker - public int Bonus {get; set;} = 0; // Current bonus tracker - To-do: bonus implementation + public int Stage { get; set; } = 0; // Current stage tracker + public int Bonus { get; set; } = 0; // Current bonus tracker - To-do: bonus implementation // public int Style = 0; // To-do: style implementation // Timing - public int Ticks {get; set;} = 0; // To-do: sub-tick counting? This currently goes on OnTick, which is not sub-tick I believe? Needs investigating + public int Ticks { get; set; } = 0; // To-do: sub-tick counting? This currently goes on OnTick, which is not sub-tick I believe? Needs investigating + + // Time Formatting + public enum TimeFormatStyle + { + Compact, + Full, + Verbose + } // Methods public void Reset() @@ -53,7 +61,7 @@ public void Tick() // without worry for any timing restrictions (eg: Paused, Enabled, etc) if (this.Paused || !this.Enabled || !this.IsRunning) return; - + this.Ticks++; } } \ No newline at end of file From 1f8946edff3439d38b0c99a34d7a8a7c7e5f1fc8 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:45:52 +0200 Subject: [PATCH 08/11] forgot leading 0s for compact type --- src/ST-Player/PlayerHUD.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index 0ce6755..ecb9a95 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -42,8 +42,8 @@ public string FormatTime(int ticks, PlayerTimer.TimeFormatStyle style = PlayerTi { case PlayerTimer.TimeFormatStyle.Compact: return time.TotalMinutes < 1 - ? $"{time.Seconds:D2}.{millis:D3}" - : $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + ? $"{time.Seconds:D1}.{millis:D3}" + : $"{time.Minutes:D1}:{time.Seconds:D1}.{millis:D3}"; case PlayerTimer.TimeFormatStyle.Full: return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; case PlayerTimer.TimeFormatStyle.Verbose: From 37a07ea2fbea8e7d0bf0b3c42bc99874a36e6a44 Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Wed, 20 Dec 2023 17:25:03 +0200 Subject: [PATCH 09/11] Revert "Merge branch 'chat-and-hud-messages' into time-format" This reverts commit f6a59892017bd3e73a25b93011111612a9ef362e, reversing changes made to 1f8946edff3439d38b0c99a34d7a8a7c7e5f1fc8. --- src/ST-Events/Players.cs | 4 +- src/ST-Events/TriggerEndTouch.cs | 6 --- src/ST-Events/TriggerStartTouch.cs | 71 +----------------------------- src/ST-Player/PlayerTimer.cs | 11 +---- 4 files changed, 6 insertions(+), 86 deletions(-) diff --git a/src/ST-Events/Players.cs b/src/ST-Events/Players.cs index 0133785..fe93343 100644 --- a/src/ST-Events/Players.cs +++ b/src/ST-Events/Players.cs @@ -104,7 +104,7 @@ public HookResult OnPlayerConnect(EventPlayerConnectFull @event, GameEventInfo i Profile); // 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}."); + Server.PrintToChatAll($"{PluginPrefix} {ChatColors.Green}{player.PlayerName}{ChatColors.Default} has connected from {playerList[player.UserId ?? 0].Profile.Country}."); Console.WriteLine($"[CS2 Surf] {player.PlayerName} has connected from {playerList[player.UserId ?? 0].Profile.Country}."); return HookResult.Continue; } @@ -123,7 +123,7 @@ public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo else { // Update data in Player DB table - Task updatePlayerTask = DB.Write($"UPDATE `Player` SET country = '{playerList[player.UserId ?? 0].Profile.Country}', `last_seen` = {(int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()}, `connections` = `connections` + 1 WHERE `id` = {playerList[player.UserId ?? 0].Profile.ID} LIMIT 1;"); + Task updatePlayerTask = DB.Write($"UPDATE `Player` SET country = '{playerList[player.UserId ?? 0].Profile.Country}', `lastseen` = {(int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()}, `connections` = `connections` + 1 WHERE `id` = {playerList[player.UserId ?? 0].Profile.ID} LIMIT 1;"); if (updatePlayerTask.Result != 1) throw new Exception($"CS2 Surf ERROR >> OnPlayerDisconnect -> Failed to update player data in database. Player: {player.PlayerName} ({player.SteamID})"); diff --git a/src/ST-Events/TriggerEndTouch.cs b/src/ST-Events/TriggerEndTouch.cs index 866c12d..e36280a 100644 --- a/src/ST-Events/TriggerEndTouch.cs +++ b/src/ST-Events/TriggerEndTouch.cs @@ -54,12 +54,6 @@ internal HookResult OnTriggerEndTouch(DynamicHook handler) #if DEBUG player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_{ChatColors.LightRed}EndTouchFunc{ChatColors.Default} -> {ChatColors.Yellow}Stage {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} Start Zone"); #endif - - // Show Prespeed for stages - will be enabled/disabled by the user? - float velocity = (float)Math.Sqrt(player.Controller.PlayerPawn.Value!.AbsVelocity.X * player.Controller.PlayerPawn.Value!.AbsVelocity.X - + player.Controller.PlayerPawn.Value!.AbsVelocity.Y * player.Controller.PlayerPawn.Value!.AbsVelocity.Y - + player.Controller.PlayerPawn.Value!.AbsVelocity.Z * player.Controller.PlayerPawn.Value!.AbsVelocity.Z); - player.Controller.PrintToCenter($"Stage {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} - Prespeed: {velocity.ToString("0")} u/s"); } } diff --git a/src/ST-Events/TriggerStartTouch.cs b/src/ST-Events/TriggerStartTouch.cs index 54c84bc..dee74ba 100644 --- a/src/ST-Events/TriggerStartTouch.cs +++ b/src/ST-Events/TriggerStartTouch.cs @@ -2,7 +2,6 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; -using System.Text.Json; namespace SurfTimer; @@ -28,15 +27,6 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_StartTouchFunc -> {trigger.DesignerName} -> {trigger.Entity!.Name}"); #endif - // Get the velocity of the player - we will be using this values to compare and write to DB - float velocity = (float)Math.Sqrt(player.Controller.PlayerPawn.Value!.AbsVelocity.X * player.Controller.PlayerPawn.Value!.AbsVelocity.X - + player.Controller.PlayerPawn.Value!.AbsVelocity.Y * player.Controller.PlayerPawn.Value!.AbsVelocity.Y - + player.Controller.PlayerPawn.Value!.AbsVelocity.Z * player.Controller.PlayerPawn.Value!.AbsVelocity.Z); - float velocity_x = player.Controller.PlayerPawn.Value!.AbsVelocity.X; - float velocity_y = player.Controller.PlayerPawn.Value!.AbsVelocity.Y; - float velocity_z = player.Controller.PlayerPawn.Value!.AbsVelocity.Z; - - if (trigger.Entity!.Name != null) { // Map end zones -- hook into map_end @@ -49,26 +39,7 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) if (player.Stats.PB[0,0] == 0 || player.Timer.Ticks < player.Stats.PB[0,0]) player.Stats.PB[0,0] = player.Timer.Ticks; player.Controller.PrintToChat($"{PluginPrefix} You finished the map in {player.HUD.FormatTime(player.Stats.PB[0,0])}!"); - - foreach (var item in player.Timer.CurrentRunCheckpoints) - { - int cp = item.GetProperty("cp").GetInt32(); - string time = item.GetProperty("time").GetString(); - int ticks = item.GetProperty("ticks").GetInt32(); - double speed = item.GetProperty("speed").GetDouble(); - double velX = item.GetProperty("velX").GetDouble(); - double velY = item.GetProperty("velY").GetDouble(); - double velZ = item.GetProperty("velZ").GetDouble(); - - Console.WriteLine($"CP: {cp} | Time: {time} | Ticks: {ticks} | Speed: {speed} | VelX: {velX} | VelY: {velY} | VelZ: {velZ}"); - - // Write new CPs to database - // Transactions? - // Task newPbTask = DB.Write($"INSERT INTO `Checkpoints` (`maptime_id`, `cp`, `runtime`, `velX`, `velY`, `velZ`) VALUES ('0', {cp}, '{ticks}', {velX}, {velY}, {velZ});"); - // int newPbTaskRows = newPbTask.Result; - // if (newPbTaskRows != 1) - // throw new Exception($"CS2 Surf ERROR >> Inserting Checkpoints."); - } + // player.Timer.Reset(); } #if DEBUG @@ -95,25 +66,7 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) int stage = Int32.Parse(Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value) - 1; player.Timer.Stage = stage; - // To-do: checkpoint functionality because stages = checkpoints when in a run on a Staged map - // To-do: This triggers more than once at random :monkaHmm: - // This should patch up re-triggering *player.Timer.CurrentRunCheckpoints.Count < stage* - if (player.Timer.IsRunning && !player.Timer.StageMode && player.Timer.CurrentRunCheckpoints.Count < stage) - { - player.Controller.PrintToChat( - $"{PluginPrefix} CP [{ChatColors.Yellow}{stage}{ChatColors.Default}]: " + - $"{ChatColors.Yellow}{player.HUD.FormatTime(player.Timer.Ticks)}{ChatColors.Default} " + - $"{ChatColors.Yellow}({velocity.ToString("0")}){ChatColors.Default} " + - $"[PB: {ChatColors.Green}-00:00.000{ChatColors.Default} " + - $"{ChatColors.Red}(-1234){ChatColors.Default} | " + - $"WR: {ChatColors.Red}+00:00.000{ChatColors.Default} " + - $"{ChatColors.Green}(+1234){ChatColors.Default}]"); - - // .... store in an array to INSERT/UPDATE in DB at the end of run? - string jsonString = $"{{ \"cp\": {stage}, \"time\": \"{player.HUD.FormatTime(player.Timer.Ticks)}\", \"ticks\": {player.Timer.Ticks}, \"speed\": {velocity}, \"velX\": {velocity_x}, \"velY\": {velocity_y}, \"velZ\": {velocity_z} }}"; - JsonElement currRunCps = JsonDocument.Parse(jsonString).RootElement; - player.Timer.CurrentRunCheckpoints.Add(currRunCps); - } + // To-do: checkpoint functionality because stages = checkpoints #if DEBUG player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_{ChatColors.Lime}StartTouchFunc{ChatColors.Default} -> {ChatColors.Yellow}Stage {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} Start Zone"); @@ -123,27 +76,7 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler) // Map checkpoint zones -- hook into map_(c)heck(p)oint# else if (Regex.Match(trigger.Entity.Name, "^map_c(p[1-9][0-9]?|heckpoint[1-9][0-9]?)$").Success) { - int checkpoint = Int32.Parse(Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value) - 1; - player.Timer.Checkpoint = checkpoint; - // To-do: checkpoint functionality - if (player.Timer.IsRunning && !player.Timer.StageMode && player.Timer.CurrentRunCheckpoints.Count < checkpoint) - { - player.Controller.PrintToChat( - $"{PluginPrefix} CP [{ChatColors.Yellow}{checkpoint}{ChatColors.Default}]: " + - $"{ChatColors.Yellow}{player.HUD.FormatTime(player.Timer.Ticks)}{ChatColors.Default} " + - $"{ChatColors.Yellow}({velocity.ToString("0")}){ChatColors.Default} " + - $"[PB: {ChatColors.Green}-00:00.000{ChatColors.Default} " + - $"{ChatColors.Red}(-1234){ChatColors.Default} | " + - $"WR: {ChatColors.Red}+00:00.000{ChatColors.Default} " + - $"{ChatColors.Green}(+1234){ChatColors.Default}]"); - - // .... store in an array to INSERT/UPDATE in DB at the end of run? - string jsonString = $"{{ \"cp\": {checkpoint}, \"time\": \"{player.HUD.FormatTime(player.Timer.Ticks)}\", \"ticks\": {player.Timer.Ticks}, \"speed\": {velocity}, \"velX\": {velocity_x}, \"velY\": {velocity_y}, \"velZ\": {velocity_z} }}"; - JsonElement currRunCps = JsonDocument.Parse(jsonString).RootElement; - player.Timer.CurrentRunCheckpoints.Add(currRunCps); - // .... store in an array to INSERT/UPDATE in DB at the end of run? - } #if DEBUG player.Controller.PrintToChat($"CS2 Surf DEBUG >> CBaseTrigger_{ChatColors.Lime}StartTouchFunc{ChatColors.Default} -> {ChatColors.LightBlue}Checkpoint {Regex.Match(trigger.Entity.Name, "[0-9][0-9]?").Value} Zone"); diff --git a/src/ST-Player/PlayerTimer.cs b/src/ST-Player/PlayerTimer.cs index 8ded292..f153908 100644 --- a/src/ST-Player/PlayerTimer.cs +++ b/src/ST-Player/PlayerTimer.cs @@ -1,6 +1,3 @@ -using System.Runtime.InteropServices; -using System.Text.Json; - namespace SurfTimer; internal class PlayerTimer @@ -15,10 +12,8 @@ internal class PlayerTimer public bool StageMode { get; set; } = false; // Stage mode toggle // Tracking - public int Stage {get; set;} = 0; // Current stage tracker - public int Checkpoint {get; set;} = 0; // Current checkpoint tracker - public List CurrentRunCheckpoints { get; set; } = new List(); // Current run cps list - public int Bonus {get; set;} = 0; // Current bonus tracker - To-do: bonus implementation + public int Stage { get; set; } = 0; // Current stage tracker + public int Bonus { get; set; } = 0; // Current bonus tracker - To-do: bonus implementation // public int Style = 0; // To-do: style implementation // Timing @@ -38,10 +33,8 @@ public void Reset() this.Stop(); this.Ticks = 0; this.Stage = 0; - this.Checkpoint = 0; this.Paused = false; this.PracticeMode = false; - this.CurrentRunCheckpoints.Clear(); } public void Pause() From e68c66a6040ebcbfa1133959d47293e98047a1ed Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Wed, 20 Dec 2023 17:28:00 +0200 Subject: [PATCH 10/11] . --- src/ST-Events/Players.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ST-Events/Players.cs b/src/ST-Events/Players.cs index fe93343..011cbaf 100644 --- a/src/ST-Events/Players.cs +++ b/src/ST-Events/Players.cs @@ -123,7 +123,7 @@ public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo else { // Update data in Player DB table - Task updatePlayerTask = DB.Write($"UPDATE `Player` SET country = '{playerList[player.UserId ?? 0].Profile.Country}', `lastseen` = {(int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()}, `connections` = `connections` + 1 WHERE `id` = {playerList[player.UserId ?? 0].Profile.ID} LIMIT 1;"); + Task updatePlayerTask = DB.Write($"UPDATE `Player` SET country = '{playerList[player.UserId ?? 0].Profile.Country}', `last_seen` = {(int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()}, `connections` = `connections` + 1 WHERE `id` = {playerList[player.UserId ?? 0].Profile.ID} LIMIT 1;"); if (updatePlayerTask.Result != 1) throw new Exception($"CS2 Surf ERROR >> OnPlayerDisconnect -> Failed to update player data in database. Player: {player.PlayerName} ({player.SteamID})"); From eb38fbbb14dd234b77726021b1976c455ca1285e Mon Sep 17 00:00:00 2001 From: T <74899888+tslashd@users.noreply.github.com> Date: Thu, 21 Dec 2023 00:59:05 +0200 Subject: [PATCH 11/11] bools naming --- src/ST-Commands/PlayerCommands.cs | 2 +- src/ST-Player/PlayerHUD.cs | 2 +- src/ST-Player/PlayerTimer.cs | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ST-Commands/PlayerCommands.cs b/src/ST-Commands/PlayerCommands.cs index 251a421..bac46fd 100644 --- a/src/ST-Commands/PlayerCommands.cs +++ b/src/ST-Commands/PlayerCommands.cs @@ -75,7 +75,7 @@ public void PlayerGoToStage(CCSPlayerController? player, CommandInfo command) Server.NextFrame(() => player.PlayerPawn.Value!.Teleport(CurrentMap.StageStartZone[stage], CurrentMap.StageStartZoneAngles[stage], new Vector(0,0,0))); playerList[player.UserId ?? 0].Timer.Reset(); - playerList[player.UserId ?? 0].Timer.StageMode = true; + playerList[player.UserId ?? 0].Timer.IsStageMode = true; // To-do: If you run this while you're in the start zone, endtouch for the start zone runs after you've teleported // causing the timer to start. This needs to be fixed. diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index ecb9a95..4814453 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -61,7 +61,7 @@ public void Display() string timerColor = "#79d1ed"; if (_player.Timer.IsRunning) { - if (_player.Timer.PracticeMode) + if (_player.Timer.IsPracticeMode) timerColor = "#F2C94C"; else timerColor = "#2E9F65"; diff --git a/src/ST-Player/PlayerTimer.cs b/src/ST-Player/PlayerTimer.cs index f153908..f12d668 100644 --- a/src/ST-Player/PlayerTimer.cs +++ b/src/ST-Player/PlayerTimer.cs @@ -3,13 +3,13 @@ namespace SurfTimer; internal class PlayerTimer { // Status - public bool Enabled { get; set; } = true; // Enable toggle for entire timer - public bool Paused { get; set; } = false; // Pause toggle for timer + public bool IsEnabled { get; set; } = true; // Enable toggle for entire timer + public bool IsPaused { get; set; } = false; // Pause toggle for timer public bool IsRunning { get; set; } = false; // Is the timer currently running? // Modes - public bool PracticeMode { get; set; } = false; // Practice mode toggle - public bool StageMode { get; set; } = false; // Stage mode toggle + public bool IsPracticeMode { get; set; } = false; // Practice mode toggle + public bool IsStageMode { get; set; } = false; // Stage mode toggle // Tracking public int Stage { get; set; } = 0; // Current stage tracker @@ -33,19 +33,19 @@ public void Reset() this.Stop(); this.Ticks = 0; this.Stage = 0; - this.Paused = false; - this.PracticeMode = false; + this.IsPaused = false; + this.IsPracticeMode = false; } public void Pause() { - this.Paused = true; + this.IsPaused = true; } public void Start() { // Timer Start method - notes: OnStartTimerPress - if (this.Enabled) + if (this.IsEnabled) this.IsRunning = true; } @@ -59,7 +59,7 @@ public void Tick() { // Tick the timer - this checks for any restrictions, so can be conveniently called from anywhere // without worry for any timing restrictions (eg: Paused, Enabled, etc) - if (this.Paused || !this.Enabled || !this.IsRunning) + if (this.IsPaused || !this.IsEnabled || !this.IsRunning) return; this.Ticks++;