From 0060dd10f74f9b3114046e1e9586f02d3acbc316 Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Mon, 5 Feb 2024 15:44:18 -0800 Subject: [PATCH 1/8] Remove silly delgate SimpleView syntax * Use collection constructor syntax instead for simpleviews (much cleaner!) * Work on beginning of new logging thing. --- .../Generic/GenericCommandNotifications.cs | 39 +++++++------- .../Jailbreak.English.csproj | 2 +- lang/Jailbreak.English/Logs/LogMessages.cs | 8 +++ .../Rebel/RebelNotifications.cs | 13 ++--- .../Teams/RatioNotifications.cs | 54 +++++++++---------- .../Warden/WardenNotifications.cs | 51 +++++++++--------- mod/Jailbreak.Logs/LogsManager.cs | 33 ++++++------ mod/Jailbreak.Teams/Ratio/RatioBehavior.cs | 1 + .../Commands/WardenCommandsBehavior.cs | 1 + .../Jailbreak.Formatting/Base/SimpleView.cs | 51 +++++++++++++----- .../Extensions/ServerExtensions.cs | 11 ++++ public/Jailbreak.Public/Utils/RoundEnd.cs | 8 +++ 12 files changed, 158 insertions(+), 114 deletions(-) create mode 100644 lang/Jailbreak.English/Logs/LogMessages.cs create mode 100644 public/Jailbreak.Public/Utils/RoundEnd.cs diff --git a/lang/Jailbreak.English/Generic/GenericCommandNotifications.cs b/lang/Jailbreak.English/Generic/GenericCommandNotifications.cs index f246b231..bf9ad7a7 100644 --- a/lang/Jailbreak.English/Generic/GenericCommandNotifications.cs +++ b/lang/Jailbreak.English/Generic/GenericCommandNotifications.cs @@ -1,4 +1,5 @@ using CounterStrikeSharp.API.Modules.Utils; + using Jailbreak.Formatting.Base; using Jailbreak.Formatting.Core; using Jailbreak.Formatting.Logistics; @@ -9,26 +10,22 @@ namespace Jailbreak.English.Generic; public class GenericCommandNotifications : IGenericCommandNotifications, ILanguage { - public static FormatObject PREFIX = - new HiddenFormatObject($" {ChatColors.Darkred}[{ChatColors.LightRed}JB{ChatColors.Darkred}]") - { - // Hide in panorama and center text - Plain = false, - Panorama = false, - Chat = true, - }; + public static FormatObject PREFIX = + new HiddenFormatObject($" {ChatColors.Darkred}[{ChatColors.LightRed}JB{ChatColors.Darkred}]") + { + // Hide in panorama and center text + Plain = false, + Panorama = false, + Chat = true + }; - public IView PlayerNotFound(string query) - { - return new SimpleView(writer => - writer - .Line(PREFIX, $"Player '{query}' not found!")); - } + public IView PlayerNotFound(string query) + { + return new SimpleView { PREFIX, $"Player '{query}' not found!" }; + } - public IView PlayerFoundMultiple(string query) - { - return new SimpleView(writer => - writer - .Line(PREFIX, $"Multiple players found for '{query}'!")); - } -} \ No newline at end of file + public IView PlayerFoundMultiple(string query) + { + return new SimpleView { PREFIX, $"Multiple players found for '{query}'!" }; + } +} diff --git a/lang/Jailbreak.English/Jailbreak.English.csproj b/lang/Jailbreak.English/Jailbreak.English.csproj index 883695e7..5b7c3e08 100644 --- a/lang/Jailbreak.English/Jailbreak.English.csproj +++ b/lang/Jailbreak.English/Jailbreak.English.csproj @@ -7,7 +7,7 @@ - + diff --git a/lang/Jailbreak.English/Logs/LogMessages.cs b/lang/Jailbreak.English/Logs/LogMessages.cs new file mode 100644 index 00000000..c5eda4da --- /dev/null +++ b/lang/Jailbreak.English/Logs/LogMessages.cs @@ -0,0 +1,8 @@ +using Jailbreak.Formatting.Logistics; + +namespace Jailbreak.English.Logs; + +public class LogMessages : ILanguage +{ + +} diff --git a/lang/Jailbreak.English/Rebel/RebelNotifications.cs b/lang/Jailbreak.English/Rebel/RebelNotifications.cs index 53ffd2ad..c4e440a6 100644 --- a/lang/Jailbreak.English/Rebel/RebelNotifications.cs +++ b/lang/Jailbreak.English/Rebel/RebelNotifications.cs @@ -1,4 +1,5 @@ using CounterStrikeSharp.API.Modules.Utils; + using Jailbreak.Formatting.Base; using Jailbreak.Formatting.Core; using Jailbreak.Formatting.Logistics; @@ -9,14 +10,14 @@ namespace Jailbreak.English.Rebel; public class RebelNotifications : IRebelNotifications, ILanguage { - public static FormatObject PREFIX = new HiddenFormatObject( $" {ChatColors.Darkred}[{ChatColors.LightRed}Rebel{ChatColors.Darkred}]" ) + public static FormatObject PREFIX = new HiddenFormatObject($" {ChatColors.Darkred}[{ChatColors.LightRed}Rebel{ChatColors.Darkred}]") { // Hide in panorama and center text Plain = false, Panorama = false, - Chat = true, + Chat = true }; - public IView NO_LONGER_REBEL => new SimpleView(writer => - writer - .Line(PREFIX, "You are no longer a rebel.")); -} \ No newline at end of file + + public IView NO_LONGER_REBEL => + new SimpleView() { PREFIX, "You are no longer a rebel." }; +} diff --git a/lang/Jailbreak.English/Teams/RatioNotifications.cs b/lang/Jailbreak.English/Teams/RatioNotifications.cs index 5747b526..b9827c7a 100644 --- a/lang/Jailbreak.English/Teams/RatioNotifications.cs +++ b/lang/Jailbreak.English/Teams/RatioNotifications.cs @@ -10,45 +10,43 @@ namespace Jailbreak.English.Teams; public class RatioNotifications : IRatioNotifications, ILanguage { - public static FormatObject PREFIX = new HiddenFormatObject( $" {ChatColors.LightRed}[{ChatColors.Red}JB{ChatColors.LightRed}]" ) + public static FormatObject PREFIX = new HiddenFormatObject($" {ChatColors.LightRed}[{ChatColors.Red}JB{ChatColors.LightRed}]") { // Hide in panorama and center text Plain = false, Panorama = false, - Chat = true, + Chat = true }; - public IView NOT_ENOUGH_GUARDS => new SimpleView(writer => - writer - .Line(PREFIX, "There's not enough guards in the queue!")); + public IView NOT_ENOUGH_GUARDS => + new SimpleView { PREFIX, "There's not enough guards in the queue!" }; - public IView PLEASE_JOIN_GUARD_QUEUE => new SimpleView(writer => - writer - .Line(PREFIX, "Type !guard to become a guard!")); + public IView PLEASE_JOIN_GUARD_QUEUE => + new SimpleView { PREFIX, "Type !guard to become a guard!" }; - public IView JOINED_GUARD_QUEUE => new SimpleView(writer => - writer - .Line(PREFIX, "You've joined the guard queue!")); + public IView JOINED_GUARD_QUEUE => + new SimpleView { PREFIX, "You've joined the guard queue!" }; - public IView ALREADY_A_GUARD => new SimpleView(writer => - writer - .Line(PREFIX, "You're already a guard!")); + public IView ALREADY_A_GUARD => + new SimpleView { PREFIX, "You're already a guard!" }; - public IView YOU_WERE_AUTOBALANCED_PRISONER => new SimpleView(writer => - writer - .Line(PREFIX, "You were autobalanced to the prisoner team!")); + public IView YOU_WERE_AUTOBALANCED_PRISONER => + new SimpleView + { + { PREFIX, "You were autobalanced to the prisoner team!" }, + { PREFIX, "Please use !guard to join the guard team." } + }; - public IView ATTEMPT_TO_JOIN_FROM_TEAM_MENU => new SimpleView(writer => - writer - .Line(PREFIX, "You were swapped back to the prisoner team!") - .Line(PREFIX, "Please use !guard to join the guard team.")); + public IView ATTEMPT_TO_JOIN_FROM_TEAM_MENU => + new SimpleView { PREFIX, "You were swapped back to the prisoner team!" }; - public IView LEFT_GUARD => new SimpleView(writer => - writer - .Line(PREFIX, "You are no longer a guard.") - .Line(PREFIX, "Please use !guard if you want to re-join the guard team.")); + public IView LEFT_GUARD => + new SimpleView + { + { PREFIX, "You are no longer a guard." }, + { PREFIX, "Please use !guard if you want to re-join the guard team." } + }; - public IView YOU_WERE_AUTOBALANCED_GUARD => new SimpleView(writer => - writer - .Line(PREFIX, "You are now a guard!")); + public IView YOU_WERE_AUTOBALANCED_GUARD => + new SimpleView { PREFIX, "You are now a guard!" }; } diff --git a/lang/Jailbreak.English/Warden/WardenNotifications.cs b/lang/Jailbreak.English/Warden/WardenNotifications.cs index 332120b5..8313aa5e 100644 --- a/lang/Jailbreak.English/Warden/WardenNotifications.cs +++ b/lang/Jailbreak.English/Warden/WardenNotifications.cs @@ -11,57 +11,54 @@ namespace Jailbreak.English.Warden; public class WardenNotifications : IWardenNotifications, ILanguage { - public static FormatObject PREFIX = new HiddenFormatObject( $" {ChatColors.Lime}[{ChatColors.Green}WARDEN{ChatColors.Lime}]" ) + public static FormatObject PREFIX = new HiddenFormatObject($" {ChatColors.Lime}[{ChatColors.Green}WARDEN{ChatColors.Lime}]") { // Hide in panorama and center text Plain = false, Panorama = false, - Chat = true, + Chat = true }; - public IView PICKING_SHORTLY => new SimpleView(writer => - writer - .Line(PREFIX, "Picking a warden shortly") - .Line(PREFIX, "To enter the warden queue, type !warden in chat.")); + public IView PICKING_SHORTLY => + new SimpleView + { + { PREFIX, "Picking a warden shortly" }, + { PREFIX, "To enter the warden queue, type !warden in chat." } + }; - public IView NO_WARDENS => new SimpleView(writer => - writer - .Line(PREFIX, "No wardens in queue! The next player to run !warden will become a warden.")); + public IView NO_WARDENS => + new SimpleView { PREFIX, "No wardens in queue! The next player to run !warden will become a warden." }; - public IView WARDEN_LEFT => new SimpleView(writer => - writer.Line(PREFIX, "The warden has left the game!")); + public IView WARDEN_LEFT => + new SimpleView { PREFIX, "The warden has left the game!" }; - public IView WARDEN_DIED => new SimpleView(writer => - writer.Line(PREFIX, "The warden has died!")); + public IView WARDEN_DIED => + new SimpleView { PREFIX, "The warden has died!" }; - public IView BECOME_NEXT_WARDEN => new SimpleView(writer => - writer.Line(PREFIX, "Type !warden to become the next warden")); + public IView BECOME_NEXT_WARDEN => + new SimpleView { PREFIX, "Type !warden to become the next warden" }; - public IView JOIN_RAFFLE => new SimpleView(writer => - writer.Line(PREFIX, "You've joined the warden raffle!")); + public IView JOIN_RAFFLE => + new SimpleView { PREFIX, "You've joined the warden raffle!" }; - public IView LEAVE_RAFFLE => new SimpleView(writer => - writer.Line(PREFIX, "You've left the warden raffle!")); + public IView LEAVE_RAFFLE => + new SimpleView { PREFIX, "You've left the warden raffle!" }; public IView PASS_WARDEN(CCSPlayerController player) { - return new SimpleView(writer => - writer.Line(PREFIX, player, "has resigned from being warden!")); + return new SimpleView { PREFIX, player, "has resigned from being warden!" }; } public IView NEW_WARDEN(CCSPlayerController player) { - return new SimpleView(writer => - writer.Line(PREFIX, player, "is now the warden!")); + return new SimpleView { PREFIX, player, "is now the warden!" }; } public IView CURRENT_WARDEN(CCSPlayerController? player) { if (player is not null) - return new SimpleView(writer => - writer.Line(PREFIX, "The current warden is", player)); + return new SimpleView { PREFIX, "The current warden is", player }; else - return new SimpleView(writer => - writer.Line(PREFIX, "There is currently no warden!")); + return new SimpleView { PREFIX, "There is currently no warden!" }; } } diff --git a/mod/Jailbreak.Logs/LogsManager.cs b/mod/Jailbreak.Logs/LogsManager.cs index 382b005d..29e1d3c5 100644 --- a/mod/Jailbreak.Logs/LogsManager.cs +++ b/mod/Jailbreak.Logs/LogsManager.cs @@ -1,6 +1,10 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; + +using Jailbreak.Formatting.Base; +using Jailbreak.Formatting.Core; +using Jailbreak.Formatting.Extensions; using Jailbreak.Public.Behaviors; using Jailbreak.Public.Extensions; using Jailbreak.Public.Mod.Logs; @@ -12,10 +16,10 @@ namespace Jailbreak.Logs; public class LogsManager : IPluginBehavior, ILogService { - private readonly List _logMessages = new(); + private readonly List _logMessages = new(); private long startTime; - private IWardenService wardenService; - private IRebelService rebelService; + private IWardenService _wardenService; + private IRebelService _rebelService; private IServiceProvider _serviceProvider; @@ -28,21 +32,15 @@ public void Start(BasePlugin parent) { parent.RegisterEventHandler(OnRoundStart); parent.RegisterEventHandler(OnRoundEnd); - wardenService = _serviceProvider.GetRequiredService(); - rebelService = _serviceProvider.GetRequiredService(); + _wardenService = _serviceProvider.GetRequiredService(); + _rebelService = _serviceProvider.GetRequiredService(); } private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { - foreach (var player in Utilities.GetPlayers()) - { - if(!player.IsReal()) - continue; - foreach (var log in _logMessages) - { - player.PrintToConsole(log); - } - } + // By default, print all logs to player consoles at the end of the round. + foreach (var log in _logMessages) + log.ToAllConsole(); return HookResult.Continue; } @@ -56,6 +54,7 @@ private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) public void AddLogMessage(string message) { + // format to [MM:SS] message string prefix = $"[{TimeSpan.FromSeconds(DateTimeOffset.Now.ToUnixTimeSeconds() - startTime):mm\\:ss}] "; _logMessages.Add(prefix + message); @@ -73,11 +72,11 @@ public void ClearLogMessages() public string FormatPlayer(CCSPlayerController player) { - if (wardenService.IsWarden(player)) + if (_wardenService.IsWarden(player)) return $"{player.PlayerName} (WARDEN)"; if (player.GetTeam() == CsTeam.CounterTerrorist) return $"{player.PlayerName} (CT)"; - if (rebelService.IsRebel(player)) + if (_rebelService.IsRebel(player)) return $"{player.PlayerName} (REBEL)"; return $"{player.PlayerName} (Prisoner)"; } @@ -115,4 +114,4 @@ private void printLogs(Delegate printFunction) printFunction.DynamicInvoke("****** END JAILBREAK LOGS ******"); printFunction.DynamicInvoke("********************************"); } -} \ No newline at end of file +} diff --git a/mod/Jailbreak.Teams/Ratio/RatioBehavior.cs b/mod/Jailbreak.Teams/Ratio/RatioBehavior.cs index 1d399f79..c154bdde 100644 --- a/mod/Jailbreak.Teams/Ratio/RatioBehavior.cs +++ b/mod/Jailbreak.Teams/Ratio/RatioBehavior.cs @@ -2,6 +2,7 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Cvars; +using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Utils; using Jailbreak.Public.Behaviors; diff --git a/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs b/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs index 4d82827c..6492d1b2 100644 --- a/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs +++ b/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs @@ -2,6 +2,7 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Commands; +using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; using Jailbreak.Formatting.Extensions; diff --git a/public/Jailbreak.Formatting/Base/SimpleView.cs b/public/Jailbreak.Formatting/Base/SimpleView.cs index 6cf13644..48210e40 100644 --- a/public/Jailbreak.Formatting/Base/SimpleView.cs +++ b/public/Jailbreak.Formatting/Base/SimpleView.cs @@ -1,30 +1,53 @@ -using Jailbreak.Formatting.Core; +using System.Collections; +using System.Text; + +using Jailbreak.Formatting.Core; namespace Jailbreak.Formatting.Base; -public class SimpleView : IView +public class SimpleView : IView, IEnumerable> { + private List> _lines = new(); - private Action _handler; + public SimpleView() + { - public SimpleView(Action handler) + } + + /// + /// Add an item to the end of the last row in this SimpleView + /// Eg, { abc, 123, weee } is all one row + /// + /// + public void Add(FormatObject item) { - _handler = handler; + if (_lines.Count == 0) + _lines.Add(new List()); + + _lines[_lines.Count - 1].Add(item); } - public SimpleView(params string[] lines) + /// + /// Add a whole new row to this simpleview + /// Eg, { { 123 }, { abc }, { weeeeee } } are each their own lines. + /// + /// + public void Add(params FormatObject[] line) { - _handler = (writer) => - { - foreach (string line in lines) - { - writer.Line(line); - } - }; + _lines.Add(new List(line)); } public void Render(FormatWriter writer) { - _handler(writer); + foreach (List formatObjects in _lines) + writer.Line(formatObjects.ToArray()); + } + + public IEnumerator> GetEnumerator() + => _lines.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); } } diff --git a/public/Jailbreak.Public/Extensions/ServerExtensions.cs b/public/Jailbreak.Public/Extensions/ServerExtensions.cs index cd058274..f730c4a7 100644 --- a/public/Jailbreak.Public/Extensions/ServerExtensions.cs +++ b/public/Jailbreak.Public/Extensions/ServerExtensions.cs @@ -1,4 +1,5 @@ using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; @@ -10,4 +11,14 @@ public static void PrintToCenterAll(string message) { VirtualFunctions.ClientPrintAll(HudDestination.Center, message, 0, 0, 0, 0); } + + /// + /// Get the current CCSGameRules for the server + /// + /// + public static CCSGameRules GetGameRules() + { + // From killstr3ak + return Utilities.FindAllEntitiesByDesignerName("cs_gamerules").First().GameRules!; + } } diff --git a/public/Jailbreak.Public/Utils/RoundEnd.cs b/public/Jailbreak.Public/Utils/RoundEnd.cs new file mode 100644 index 00000000..9a34f755 --- /dev/null +++ b/public/Jailbreak.Public/Utils/RoundEnd.cs @@ -0,0 +1,8 @@ +using CounterStrikeSharp.API.Modules.Cvars; + +namespace Jailbreak.Public.Utils; + +public static class RoundEnd +{ + +} From d10a262e9fac4c767dd3855cee5910c62ef3bb52 Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:21:12 -0800 Subject: [PATCH 2/8] Work on translations, boil down LogManager * Remove most stuff from LogManager, into their own classes & services * Add PlayerTagHelper as an experimental service to avoid dependency loop shenanigans in main classes * Add LogMessages as an english translation * Add ToServerConsole IView extension --- lang/Jailbreak.English/Logs/LogMessages.cs | 30 +++++- mod/Jailbreak.Logs/LogsListeners.cs | 14 +-- mod/Jailbreak.Logs/LogsManager.cs | 97 ++++++++----------- mod/Jailbreak.Logs/LogsServiceExtension.cs | 20 ++-- mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs | 44 +++++++++ mod/Jailbreak.Rebel/RebelManager.cs | 4 +- mod/Jailbreak.Warden/Global/WardenBehavior.cs | 4 +- .../Extensions/ViewExtensions.cs | 12 +++ .../Logistics/LanguageConfig.cs | 8 +- .../Views/ILogMessages.cs | 39 ++++++++ .../Views/IRichPlayerTag.cs | 15 +++ .../Jailbreak.Public/Mod/Logs/ILogService.cs | 9 +- .../Jailbreak.Public/Mod/Logs/IPlayerTag.cs | 13 +++ src/Jailbreak/JailbreakServiceCollection.cs | 2 + 14 files changed, 227 insertions(+), 84 deletions(-) create mode 100644 mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs create mode 100644 public/Jailbreak.Formatting/Views/ILogMessages.cs create mode 100644 public/Jailbreak.Formatting/Views/IRichPlayerTag.cs create mode 100644 public/Jailbreak.Public/Mod/Logs/IPlayerTag.cs diff --git a/lang/Jailbreak.English/Logs/LogMessages.cs b/lang/Jailbreak.English/Logs/LogMessages.cs index c5eda4da..3b446565 100644 --- a/lang/Jailbreak.English/Logs/LogMessages.cs +++ b/lang/Jailbreak.English/Logs/LogMessages.cs @@ -1,8 +1,34 @@ -using Jailbreak.Formatting.Logistics; +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Modules.Utils; + +using Jailbreak.Formatting.Base; +using Jailbreak.Formatting.Core; +using Jailbreak.Formatting.Logistics; +using Jailbreak.Formatting.Objects; +using Jailbreak.Formatting.Views; +using Jailbreak.Public.Extensions; namespace Jailbreak.English.Logs; -public class LogMessages : ILanguage +public class LogMessages : ILogMessages, ILanguage { + + + public IView BEGIN_JAILBREAK_LOGS => new SimpleView() + { + { "********************************" }, + { "***** BEGIN JAILBREAK LOGS *****" }, + { "********************************" } + }; + + public IView END_JAILBREAK_LOGS => new SimpleView() + { + { "********************************" }, + { "****** END JAILBREAK LOGS ******" }, + { "********************************" } + }; + + + } diff --git a/mod/Jailbreak.Logs/LogsListeners.cs b/mod/Jailbreak.Logs/LogsListeners.cs index 50fc0f5e..12957f6b 100644 --- a/mod/Jailbreak.Logs/LogsListeners.cs +++ b/mod/Jailbreak.Logs/LogsListeners.cs @@ -36,7 +36,7 @@ private HookResult OnButtonPressed(CEntityIOOutput output, string name, CEntityI CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); if (!ent.IsValid) return HookResult.Continue; - logs.AddLogMessage( + logs.Append( $"{logs.FormatPlayer(pawn.OriginalController.Value!)} pressed a button {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); return HookResult.Continue; } @@ -48,7 +48,7 @@ private HookResult OnGrenadeThrown(EventGrenadeThrown @event, GameEventInfo info return HookResult.Continue; var grenade = @event.Weapon; - logs.AddLogMessage($"{logs.FormatPlayer(player)} threw a {grenade}"); + logs.Append($"{logs.FormatPlayer(player)} threw a {grenade}"); return HookResult.Continue; } @@ -67,26 +67,26 @@ private HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) { if (health > 0) { - logs.AddLogMessage($"The world hurt {logs.FormatPlayer(player)} for {health} damage"); + logs.Append($"The world hurt {logs.FormatPlayer(player)} for {health} damage"); } else { - logs.AddLogMessage($"The world killed {logs.FormatPlayer(player)}"); + logs.Append($"The world killed {logs.FormatPlayer(player)}"); } } else { if (health > 0) { - logs.AddLogMessage( + logs.Append( $"{logs.FormatPlayer(attacker!)} hurt {logs.FormatPlayer(player)} for {health} damage"); } else { - logs.AddLogMessage($"{logs.FormatPlayer(attacker!)} killed {logs.FormatPlayer(player)}"); + logs.Append($"{logs.FormatPlayer(attacker!)} killed {logs.FormatPlayer(player)}"); } } return HookResult.Continue; } -} \ No newline at end of file +} diff --git a/mod/Jailbreak.Logs/LogsManager.cs b/mod/Jailbreak.Logs/LogsManager.cs index 29e1d3c5..b4294f12 100644 --- a/mod/Jailbreak.Logs/LogsManager.cs +++ b/mod/Jailbreak.Logs/LogsManager.cs @@ -1,10 +1,13 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Utils; using Jailbreak.Formatting.Base; using Jailbreak.Formatting.Core; using Jailbreak.Formatting.Extensions; +using Jailbreak.Formatting.Objects; +using Jailbreak.Formatting.Views; using Jailbreak.Public.Behaviors; using Jailbreak.Public.Extensions; using Jailbreak.Public.Mod.Logs; @@ -17,101 +20,81 @@ namespace Jailbreak.Logs; public class LogsManager : IPluginBehavior, ILogService { private readonly List _logMessages = new(); - private long startTime; - private IWardenService _wardenService; - private IRebelService _rebelService; - private IServiceProvider _serviceProvider; + private ILogMessages _messages; - public LogsManager(IServiceProvider serviceProvider) + public LogsManager(IServiceProvider serviceProvider, ILogMessages messages) { - _serviceProvider = serviceProvider; - } + _messages = messages; - public void Start(BasePlugin parent) - { - parent.RegisterEventHandler(OnRoundStart); - parent.RegisterEventHandler(OnRoundEnd); - _wardenService = _serviceProvider.GetRequiredService(); - _rebelService = _serviceProvider.GetRequiredService(); } + [GameEventHandler] private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { + _messages.BEGIN_JAILBREAK_LOGS + .ToServerConsole() + .ToAllConsole(); + // By default, print all logs to player consoles at the end of the round. foreach (var log in _logMessages) - log.ToAllConsole(); + log.ToServerConsole() + .ToAllConsole(); + + _messages.END_JAILBREAK_LOGS + .ToServerConsole() + .ToAllConsole(); return HookResult.Continue; } + [GameEventHandler] private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) { - startTime = DateTimeOffset.Now.ToUnixTimeSeconds(); - ClearLogMessages(); + Clear(); return HookResult.Continue; } - public void AddLogMessage(string message) + public void Append(params FormatObject[] objects) { - - // format to [MM:SS] message - string prefix = $"[{TimeSpan.FromSeconds(DateTimeOffset.Now.ToUnixTimeSeconds() - startTime):mm\\:ss}] "; - _logMessages.Add(prefix + message); + _logMessages.Add(_messages.CREATE_LOG(objects)); } - public ICollection GetLogMessages() + public void Append(string message) { - return _logMessages; + _logMessages.Add(_messages.CREATE_LOG(message)); } - public void ClearLogMessages() + public IEnumerable GetMessages() { - _logMessages.Clear(); + return _logMessages.SelectMany(view => view.ToWriter().Plain); } - public string FormatPlayer(CCSPlayerController player) + public void Clear() { - if (_wardenService.IsWarden(player)) - return $"{player.PlayerName} (WARDEN)"; - if (player.GetTeam() == CsTeam.CounterTerrorist) - return $"{player.PlayerName} (CT)"; - if (_rebelService.IsRebel(player)) - return $"{player.PlayerName} (REBEL)"; - return $"{player.PlayerName} (Prisoner)"; + _logMessages.Clear(); } - public void PrintLogs(CCSPlayerController? player) { - if (player == null) + if (player == null || !player.IsReal()) { - printLogs(Server.PrintToConsole); - } - else if (player.IsReal()) - { - printLogs(player.PrintToConsole); - } - } + _messages.BEGIN_JAILBREAK_LOGS + .ToServerConsole(); + foreach (var log in _logMessages) + log.ToServerConsole(); + _messages.END_JAILBREAK_LOGS + .ToServerConsole(); - private void printLogs(Delegate printFunction) - { - if (!GetLogMessages().Any()) - { - printFunction.DynamicInvoke("No logs to display."); return; } - printFunction.DynamicInvoke("********************************"); - printFunction.DynamicInvoke("***** BEGIN JAILBREAK LOGS *****"); - printFunction.DynamicInvoke("********************************"); - foreach (string log in GetLogMessages()) - { - printFunction.DynamicInvoke(log); - } - printFunction.DynamicInvoke("********************************"); - printFunction.DynamicInvoke("****** END JAILBREAK LOGS ******"); - printFunction.DynamicInvoke("********************************"); + _messages.BEGIN_JAILBREAK_LOGS + .ToPlayerConsole(player); + foreach (var log in _logMessages) + log.ToPlayerConsole(player); + _messages.END_JAILBREAK_LOGS + .ToPlayerConsole(player); } } diff --git a/mod/Jailbreak.Logs/LogsServiceExtension.cs b/mod/Jailbreak.Logs/LogsServiceExtension.cs index 4c626273..122f6af5 100644 --- a/mod/Jailbreak.Logs/LogsServiceExtension.cs +++ b/mod/Jailbreak.Logs/LogsServiceExtension.cs @@ -1,4 +1,6 @@ -using Jailbreak.Public.Extensions; +using Jailbreak.Formatting.Views; +using Jailbreak.Logs.Tags; +using Jailbreak.Public.Extensions; using Jailbreak.Public.Mod.Logs; using Microsoft.Extensions.DependencyInjection; @@ -8,9 +10,13 @@ public static class LogsServiceExtension { public static void AddJailbreakLogs(this IServiceCollection services) { - services.AddPluginBehavior(); - - services.AddPluginBehavior(); - services.AddPluginBehavior(); - } -} \ No newline at end of file + services.AddPluginBehavior(); + + services.AddPluginBehavior(); + services.AddPluginBehavior(); + + // PlayerTagHelper is a lower-level class that avoids dependency loops. + services.AddTransient(); + services.AddTransient(); + } +} diff --git a/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs b/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs new file mode 100644 index 00000000..62ef7d07 --- /dev/null +++ b/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs @@ -0,0 +1,44 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; + +using Jailbreak.Formatting.Core; +using Jailbreak.Formatting.Objects; +using Jailbreak.Formatting.Views; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.Logs; +using Jailbreak.Public.Mod.Rebel; +using Jailbreak.Public.Mod.Warden; + +using Microsoft.Extensions.DependencyInjection; + +namespace Jailbreak.Logs.Tags; + +public class PlayerTagHelper : IRichPlayerTag, IPlayerTag +{ + private IWardenService _wardenService; + private IRebelService _rebelService; + + public PlayerTagHelper(IServiceProvider provider) + { + // Lazy-load dependencies to avoid loops, since we are a lower-level class. + _wardenService = provider.GetRequiredService(); + _rebelService = provider.GetRequiredService(); + } + + public FormatObject Rich(CCSPlayerController player) + { + if (_wardenService.IsWarden(player)) + return new StringFormatObject("(WARDEN)", ChatColors.DarkBlue); + if (player.GetTeam() == CsTeam.CounterTerrorist) + return new StringFormatObject("(CT)", ChatColors.BlueGrey); + if (_rebelService.IsRebel(player)) + return new StringFormatObject("(REBEL)", ChatColors.Darkred); + + return new StringFormatObject("(T)", ChatColors.Yellow); + } + + public string Plain(CCSPlayerController playerController) + { + return $"{playerController.PlayerName} [#{playerController.UserId}] {Rich(playerController).ToPlain()}"; + } +} diff --git a/mod/Jailbreak.Rebel/RebelManager.cs b/mod/Jailbreak.Rebel/RebelManager.cs index 61d6203d..d2909a58 100644 --- a/mod/Jailbreak.Rebel/RebelManager.cs +++ b/mod/Jailbreak.Rebel/RebelManager.cs @@ -117,7 +117,7 @@ public bool MarkRebel(CCSPlayerController player, long time = 120) { if (!rebelTimes.ContainsKey(player)) { - logs.AddLogMessage(player.PlayerName + " is now a rebel."); + logs.Append(player.PlayerName + " is now a rebel."); } rebelTimes[player] = DateTimeOffset.Now.ToUnixTimeSeconds() + time; @@ -128,7 +128,7 @@ public bool MarkRebel(CCSPlayerController player, long time = 120) public void UnmarkRebel(CCSPlayerController player) { notifs.NO_LONGER_REBEL.ToPlayerChat(player); - logs.AddLogMessage(player.PlayerName + " is no longer a rebel."); + logs.Append(player.PlayerName + " is no longer a rebel."); rebelTimes.Remove(player); ApplyRebelColor(player); diff --git a/mod/Jailbreak.Warden/Global/WardenBehavior.cs b/mod/Jailbreak.Warden/Global/WardenBehavior.cs index ad5cc0bf..05c05dbc 100644 --- a/mod/Jailbreak.Warden/Global/WardenBehavior.cs +++ b/mod/Jailbreak.Warden/Global/WardenBehavior.cs @@ -71,7 +71,7 @@ public bool TrySetWarden(CCSPlayerController controller) .ToAllChat() .ToAllCenter(); - logs.AddLogMessage($"{_warden.PlayerName} is now the warden."); + logs.Append($"{_warden.PlayerName} is now the warden."); return true; } @@ -87,7 +87,7 @@ public bool TryRemoveWarden() _warden.Pawn.Value.RenderMode = RenderMode_t.kRenderTransColor; _warden.Pawn.Value.Render = Color.FromArgb(254, 255, 255, 255); Utilities.SetStateChanged(_warden.Pawn.Value, "CBaseModelEntity", "m_clrRender"); - logs.AddLogMessage($"{_warden.PlayerName} is no longer the warden."); + logs.Append($"{_warden.PlayerName} is no longer the warden."); } _warden = null; diff --git a/public/Jailbreak.Formatting/Extensions/ViewExtensions.cs b/public/Jailbreak.Formatting/Extensions/ViewExtensions.cs index 981f483a..4d0663b6 100644 --- a/public/Jailbreak.Formatting/Extensions/ViewExtensions.cs +++ b/public/Jailbreak.Formatting/Extensions/ViewExtensions.cs @@ -18,6 +18,18 @@ public static FormatWriter ToWriter(this IView view) return writer; } + public static IView ToServerConsole(this IView view) + { + var writer = view.ToWriter(); + + foreach (string s in writer.Plain) + { + Server.PrintToConsole(s); + } + + return view; + } + #region Individual public static IView ToPlayerConsole(this IView view, CCSPlayerController player) diff --git a/public/Jailbreak.Formatting/Logistics/LanguageConfig.cs b/public/Jailbreak.Formatting/Logistics/LanguageConfig.cs index 3848bfc8..43a22a42 100644 --- a/public/Jailbreak.Formatting/Logistics/LanguageConfig.cs +++ b/public/Jailbreak.Formatting/Logistics/LanguageConfig.cs @@ -18,7 +18,7 @@ public LanguageConfig(IServiceCollection collection) public void WithGenericCommand() where TGenericCommand : class, ILanguage, IGenericCommandNotifications => _collection.AddSingleton(); - + public void WithRatio() where TRatio : class, ILanguage, IRatioNotifications => _collection.AddSingleton(); @@ -26,8 +26,12 @@ public void WithRatio() public void WithWarden() where TWarden : class, ILanguage, IWardenNotifications => _collection.AddSingleton(); - + public void WithRebel() where TRebel : class, ILanguage, IRebelNotifications => _collection.AddSingleton(); + + public void WithLogging() + where TLogging : class, ILanguage, ILogMessages + => _collection.AddSingleton(); } diff --git a/public/Jailbreak.Formatting/Views/ILogMessages.cs b/public/Jailbreak.Formatting/Views/ILogMessages.cs new file mode 100644 index 00000000..759cae8e --- /dev/null +++ b/public/Jailbreak.Formatting/Views/ILogMessages.cs @@ -0,0 +1,39 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Modules.Utils; + +using Jailbreak.Formatting.Base; +using Jailbreak.Formatting.Core; +using Jailbreak.Formatting.Objects; +using Jailbreak.Public.Extensions; + +namespace Jailbreak.Formatting.Views; + +public interface ILogMessages +{ + + public FormatObject TIME() + { + var gamerules = ServerExtensions.GetGameRules(); + var start = gamerules.RoundStartTime; + var current = Server.CurrentTime; + var elapsed = current - start; + + var minutes = Math.Floor(elapsed / 60f).ToString("00"); + var seconds = Math.Floor(elapsed % 60).ToString("00"); + + return new StringFormatObject($"[{minutes}:{seconds}]", ChatColors.Gold); + } + + public IView CREATE_LOG(params FormatObject[] objects) + { + return new SimpleView() + { + TIME(), + objects + }; + } + + public IView BEGIN_JAILBREAK_LOGS { get; } + + public IView END_JAILBREAK_LOGS { get; } +} diff --git a/public/Jailbreak.Formatting/Views/IRichPlayerTag.cs b/public/Jailbreak.Formatting/Views/IRichPlayerTag.cs new file mode 100644 index 00000000..0c14809a --- /dev/null +++ b/public/Jailbreak.Formatting/Views/IRichPlayerTag.cs @@ -0,0 +1,15 @@ +using CounterStrikeSharp.API.Core; + +using Jailbreak.Formatting.Core; + +namespace Jailbreak.Formatting.Views; + +public interface IRichPlayerTag +{ + /// + /// Get a tag for this player, which contains context about the player's current actions + /// + /// + /// + FormatObject Rich(CCSPlayerController player); +} diff --git a/public/Jailbreak.Public/Mod/Logs/ILogService.cs b/public/Jailbreak.Public/Mod/Logs/ILogService.cs index 8e528f62..4be4b511 100644 --- a/public/Jailbreak.Public/Mod/Logs/ILogService.cs +++ b/public/Jailbreak.Public/Mod/Logs/ILogService.cs @@ -4,9 +4,8 @@ namespace Jailbreak.Public.Mod.Logs; public interface ILogService { - void AddLogMessage(string message); - ICollection GetLogMessages(); - void ClearLogMessages(); - string FormatPlayer(CCSPlayerController player); + void Append(string message); + IEnumerable GetMessages(); + void Clear(); void PrintLogs(CCSPlayerController? player); -} \ No newline at end of file +} diff --git a/public/Jailbreak.Public/Mod/Logs/IPlayerTag.cs b/public/Jailbreak.Public/Mod/Logs/IPlayerTag.cs new file mode 100644 index 00000000..dbdc79ff --- /dev/null +++ b/public/Jailbreak.Public/Mod/Logs/IPlayerTag.cs @@ -0,0 +1,13 @@ +using CounterStrikeSharp.API.Core; + +namespace Jailbreak.Public.Mod.Logs; + +public interface IPlayerTag +{ + /// + /// Get a tag that contains context about the player. + /// + /// + /// + string Plain(CCSPlayerController playerController); +} diff --git a/src/Jailbreak/JailbreakServiceCollection.cs b/src/Jailbreak/JailbreakServiceCollection.cs index d1046809..58fbd4ab 100644 --- a/src/Jailbreak/JailbreakServiceCollection.cs +++ b/src/Jailbreak/JailbreakServiceCollection.cs @@ -5,6 +5,7 @@ using Jailbreak.Config; using Jailbreak.Debug; using Jailbreak.English.Generic; +using Jailbreak.English.Logs; using Jailbreak.English.Rebel; using Jailbreak.English.Teams; using Jailbreak.English.Warden; @@ -48,6 +49,7 @@ public void ConfigureServices(IServiceCollection serviceCollection) config.WithRatio(); config.WithWarden(); config.WithRebel(); + config.WithLogging(); }); } } From 53fab1a0cd299eb43c22e23d24651259e6196d98 Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:04:59 -0800 Subject: [PATCH 3/8] Add rich log service, redo simpleview semantics again, convert existing logging * Fully add rich logging service * Redo Simpleview to use a specific "Newline" struct for explicit newlines --- lang/Jailbreak.English/Logs/LogMessages.cs | 8 +- .../Teams/RatioNotifications.cs | 4 +- .../Warden/WardenNotifications.cs | 2 +- .../Listeners/LogDamageListeners.cs | 72 +++++++++++++++ .../Listeners/LogEntityListeners.cs | 38 ++++++++ mod/Jailbreak.Logs/LogsListeners.cs | 92 ------------------- mod/Jailbreak.Logs/LogsManager.cs | 21 ++++- mod/Jailbreak.Logs/LogsServiceExtension.cs | 7 +- mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs | 15 +-- mod/Jailbreak.Rebel/RebelManager.cs | 14 +-- mod/Jailbreak.Warden/Global/WardenBehavior.cs | 12 +-- .../Jailbreak.Formatting/Base/SimpleView.cs | 24 ++++- .../Objects/TreeFormatObject.cs | 86 +++++++++++++++++ .../Views/Logging/IRichLogService.cs | 13 +++ .../Views/{ => Logging}/IRichPlayerTag.cs | 3 +- 15 files changed, 281 insertions(+), 130 deletions(-) create mode 100644 mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs create mode 100644 mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs delete mode 100644 mod/Jailbreak.Logs/LogsListeners.cs create mode 100644 public/Jailbreak.Formatting/Objects/TreeFormatObject.cs create mode 100644 public/Jailbreak.Formatting/Views/Logging/IRichLogService.cs rename public/Jailbreak.Formatting/Views/{ => Logging}/IRichPlayerTag.cs (81%) diff --git a/lang/Jailbreak.English/Logs/LogMessages.cs b/lang/Jailbreak.English/Logs/LogMessages.cs index 3b446565..cb4af609 100644 --- a/lang/Jailbreak.English/Logs/LogMessages.cs +++ b/lang/Jailbreak.English/Logs/LogMessages.cs @@ -17,15 +17,15 @@ public class LogMessages : ILogMessages, ILanguage public IView BEGIN_JAILBREAK_LOGS => new SimpleView() { - { "********************************" }, - { "***** BEGIN JAILBREAK LOGS *****" }, + { "********************************" }, SimpleView.NEWLINE, + { "***** BEGIN JAILBREAK LOGS *****" }, SimpleView.NEWLINE, { "********************************" } }; public IView END_JAILBREAK_LOGS => new SimpleView() { - { "********************************" }, - { "****** END JAILBREAK LOGS ******" }, + { "********************************" }, SimpleView.NEWLINE, + { "****** END JAILBREAK LOGS ******" }, SimpleView.NEWLINE, { "********************************" } }; diff --git a/lang/Jailbreak.English/Teams/RatioNotifications.cs b/lang/Jailbreak.English/Teams/RatioNotifications.cs index b9827c7a..f9ed4476 100644 --- a/lang/Jailbreak.English/Teams/RatioNotifications.cs +++ b/lang/Jailbreak.English/Teams/RatioNotifications.cs @@ -33,7 +33,7 @@ public class RatioNotifications : IRatioNotifications, ILanguage new SimpleView { - { PREFIX, "You were autobalanced to the prisoner team!" }, + { PREFIX, "You were autobalanced to the prisoner team!" }, SimpleView.NEWLINE, { PREFIX, "Please use !guard to join the guard team." } }; @@ -43,7 +43,7 @@ public class RatioNotifications : IRatioNotifications, ILanguage new SimpleView { - { PREFIX, "You are no longer a guard." }, + { PREFIX, "You are no longer a guard." }, SimpleView.NEWLINE, { PREFIX, "Please use !guard if you want to re-join the guard team." } }; diff --git a/lang/Jailbreak.English/Warden/WardenNotifications.cs b/lang/Jailbreak.English/Warden/WardenNotifications.cs index 8313aa5e..1101b8fd 100644 --- a/lang/Jailbreak.English/Warden/WardenNotifications.cs +++ b/lang/Jailbreak.English/Warden/WardenNotifications.cs @@ -22,7 +22,7 @@ public class WardenNotifications : IWardenNotifications, ILanguage new SimpleView { - { PREFIX, "Picking a warden shortly" }, + { PREFIX, "Picking a warden shortly" }, SimpleView.NEWLINE, { PREFIX, "To enter the warden queue, type !warden in chat." } }; diff --git a/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs b/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs new file mode 100644 index 00000000..db78ec07 --- /dev/null +++ b/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs @@ -0,0 +1,72 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; + +using Jailbreak.Formatting.Views; +using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.Logs; + +namespace Jailbreak.Logs; + +public class LogDamageListeners : IPluginBehavior +{ + private readonly IRichLogService _logs; + + public LogDamageListeners(IRichLogService logs) + { + _logs = logs; + } + + + + [GameEventHandler] + public HookResult OnGrenadeThrown(EventGrenadeThrown @event, GameEventInfo info) + { + var player = @event.Userid; + if (!player.IsReal()) + return HookResult.Continue; + var grenade = @event.Weapon; + + _logs.Append(_logs.Player(player), $"threw a {grenade}"); + + return HookResult.Continue; + } + + [GameEventHandler] + public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) + { + var player = @event.Userid; + if (!player.IsReal()) + return HookResult.Continue; + var attacker = @event.Attacker; + + bool isWorld = attacker == null || !attacker.IsReal(); + int health = @event.DmgHealth; + + if (isWorld) + { + if (health > 0) + { + _logs.Append($"The world hurt", _logs.Player(player), $"for {health} damage"); + } + else + { + _logs.Append("The world killed", _logs.Player(player)); + } + } + else + { + if (health > 0) + { + _logs.Append( _logs.Player(attacker), "hurt", _logs.Player(player), $"for {health} damage"); + } + else + { + _logs.Append(_logs.Player(attacker!), "killed", _logs.Player(player)); + } + } + + return HookResult.Continue; + } +} diff --git a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs new file mode 100644 index 00000000..c2c7fe8a --- /dev/null +++ b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs @@ -0,0 +1,38 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; + +using Jailbreak.Formatting.Views; +using Jailbreak.Public.Behaviors; + +namespace Jailbreak.Logs; + +public class LogEntityListeners : IPluginBehavior +{ + private readonly IRichLogService _logs; + + public LogEntityListeners(IRichLogService logs) + { + _logs = logs; + } + + [EntityOutputHook("func_button", "OnPressed")] + public HookResult OnButtonPressed(CEntityIOOutput output, string name, CEntityInstance activator, + CEntityInstance caller, CVariant value, float delay) + { + if (!activator.IsValid) + return HookResult.Continue; + int index = (int)activator.Index; + CCSPlayerPawn? pawn = Utilities.GetEntityFromIndex(index); + if (!pawn.IsValid) + return HookResult.Continue; + if (!pawn.OriginalController.IsValid) + return HookResult.Continue; + CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); + if (!ent.IsValid) + return HookResult.Continue; + _logs.Append( + $"{_logs.Player(pawn.OriginalController.Value!)} pressed a button {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); + return HookResult.Continue; + } +} diff --git a/mod/Jailbreak.Logs/LogsListeners.cs b/mod/Jailbreak.Logs/LogsListeners.cs deleted file mode 100644 index 12957f6b..00000000 --- a/mod/Jailbreak.Logs/LogsListeners.cs +++ /dev/null @@ -1,92 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using Jailbreak.Public.Behaviors; -using Jailbreak.Public.Extensions; -using Jailbreak.Public.Mod.Logs; - -namespace Jailbreak.Logs; - -public class LogsListeners : IPluginBehavior -{ - private ILogService logs; - - public LogsListeners(ILogService logs) - { - this.logs = logs; - } - - public void Start(BasePlugin parent) - { - parent.RegisterEventHandler(OnPlayerHurt); - parent.RegisterEventHandler(OnGrenadeThrown); - parent.HookEntityOutput("func_button", "OnPressed", OnButtonPressed); - } - - private HookResult OnButtonPressed(CEntityIOOutput output, string name, CEntityInstance activator, - CEntityInstance caller, CVariant value, float delay) - { - if (!activator.IsValid) - return HookResult.Continue; - int index = (int)activator.Index; - CCSPlayerPawn? pawn = Utilities.GetEntityFromIndex(index); - if (!pawn.IsValid) - return HookResult.Continue; - if (!pawn.OriginalController.IsValid) - return HookResult.Continue; - CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); - if (!ent.IsValid) - return HookResult.Continue; - logs.Append( - $"{logs.FormatPlayer(pawn.OriginalController.Value!)} pressed a button {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); - return HookResult.Continue; - } - - private HookResult OnGrenadeThrown(EventGrenadeThrown @event, GameEventInfo info) - { - var player = @event.Userid; - if (!player.IsReal()) - return HookResult.Continue; - var grenade = @event.Weapon; - - logs.Append($"{logs.FormatPlayer(player)} threw a {grenade}"); - - return HookResult.Continue; - } - - private HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info) - { - var player = @event.Userid; - if (!player.IsReal()) - return HookResult.Continue; - var attacker = @event.Attacker; - - bool isWorld = attacker == null || !attacker.IsReal(); - int health = @event.DmgHealth; - - if (isWorld) - { - if (health > 0) - { - logs.Append($"The world hurt {logs.FormatPlayer(player)} for {health} damage"); - } - else - { - logs.Append($"The world killed {logs.FormatPlayer(player)}"); - } - } - else - { - if (health > 0) - { - logs.Append( - $"{logs.FormatPlayer(attacker!)} hurt {logs.FormatPlayer(player)} for {health} damage"); - } - else - { - logs.Append($"{logs.FormatPlayer(attacker!)} killed {logs.FormatPlayer(player)}"); - } - } - - return HookResult.Continue; - } -} diff --git a/mod/Jailbreak.Logs/LogsManager.cs b/mod/Jailbreak.Logs/LogsManager.cs index b4294f12..253f52f4 100644 --- a/mod/Jailbreak.Logs/LogsManager.cs +++ b/mod/Jailbreak.Logs/LogsManager.cs @@ -17,20 +17,21 @@ namespace Jailbreak.Logs; -public class LogsManager : IPluginBehavior, ILogService +public class LogsManager : IPluginBehavior, ILogService, IRichLogService { private readonly List _logMessages = new(); + private IRichPlayerTag _richPlayerTag; private ILogMessages _messages; - public LogsManager(IServiceProvider serviceProvider, ILogMessages messages) + public LogsManager(IServiceProvider serviceProvider, ILogMessages messages, IRichPlayerTag richPlayerTag) { _messages = messages; - + _richPlayerTag = richPlayerTag; } [GameEventHandler] - private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) + public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { _messages.BEGIN_JAILBREAK_LOGS .ToServerConsole() @@ -49,7 +50,7 @@ private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) } [GameEventHandler] - private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) + public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) { Clear(); return HookResult.Continue; @@ -60,6 +61,16 @@ public void Append(params FormatObject[] objects) _logMessages.Add(_messages.CREATE_LOG(objects)); } + public FormatObject Player(CCSPlayerController playerController) + { + return new TreeFormatObject() + { + playerController, + $"[{playerController.UserId}]", + _richPlayerTag.Rich(playerController) + }; + } + public void Append(string message) { _logMessages.Add(_messages.CREATE_LOG(message)); diff --git a/mod/Jailbreak.Logs/LogsServiceExtension.cs b/mod/Jailbreak.Logs/LogsServiceExtension.cs index 122f6af5..71e203ac 100644 --- a/mod/Jailbreak.Logs/LogsServiceExtension.cs +++ b/mod/Jailbreak.Logs/LogsServiceExtension.cs @@ -10,10 +10,13 @@ public static class LogsServiceExtension { public static void AddJailbreakLogs(this IServiceCollection services) { - services.AddPluginBehavior(); + services.AddPluginBehavior(); + services.AddTransient(provider => provider.GetRequiredService()); services.AddPluginBehavior(); - services.AddPluginBehavior(); + + services.AddPluginBehavior(); + services.AddPluginBehavior(); // PlayerTagHelper is a lower-level class that avoids dependency loops. services.AddTransient(); diff --git a/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs b/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs index 62ef7d07..ce028415 100644 --- a/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs +++ b/mod/Jailbreak.Logs/Tags/PlayerTagHelper.cs @@ -4,6 +4,7 @@ using Jailbreak.Formatting.Core; using Jailbreak.Formatting.Objects; using Jailbreak.Formatting.Views; +using Jailbreak.Public.Behaviors; using Jailbreak.Public.Extensions; using Jailbreak.Public.Mod.Logs; using Jailbreak.Public.Mod.Rebel; @@ -15,23 +16,23 @@ namespace Jailbreak.Logs.Tags; public class PlayerTagHelper : IRichPlayerTag, IPlayerTag { - private IWardenService _wardenService; - private IRebelService _rebelService; + private Lazy _wardenService; + private Lazy _rebelService; public PlayerTagHelper(IServiceProvider provider) { // Lazy-load dependencies to avoid loops, since we are a lower-level class. - _wardenService = provider.GetRequiredService(); - _rebelService = provider.GetRequiredService(); + _wardenService = new ( () => provider.GetRequiredService() ); + _rebelService = new ( () => provider.GetRequiredService() ); } public FormatObject Rich(CCSPlayerController player) { - if (_wardenService.IsWarden(player)) + if (_wardenService.Value.IsWarden(player)) return new StringFormatObject("(WARDEN)", ChatColors.DarkBlue); if (player.GetTeam() == CsTeam.CounterTerrorist) return new StringFormatObject("(CT)", ChatColors.BlueGrey); - if (_rebelService.IsRebel(player)) + if (_rebelService.Value.IsRebel(player)) return new StringFormatObject("(REBEL)", ChatColors.Darkred); return new StringFormatObject("(T)", ChatColors.Yellow); @@ -39,6 +40,6 @@ public FormatObject Rich(CCSPlayerController player) public string Plain(CCSPlayerController playerController) { - return $"{playerController.PlayerName} [#{playerController.UserId}] {Rich(playerController).ToPlain()}"; + return Rich(playerController).ToPlain(); } } diff --git a/mod/Jailbreak.Rebel/RebelManager.cs b/mod/Jailbreak.Rebel/RebelManager.cs index d2909a58..359c2bdc 100644 --- a/mod/Jailbreak.Rebel/RebelManager.cs +++ b/mod/Jailbreak.Rebel/RebelManager.cs @@ -16,12 +16,12 @@ public class RebelManager : IPluginBehavior, IRebelService { private Dictionary rebelTimes = new(); private IRebelNotifications notifs; - private ILogService logs; + private readonly IRichLogService _logs; - public RebelManager(IRebelNotifications notifs, ILogService logs) + public RebelManager(IRebelNotifications notifs, IRichLogService logs) { this.notifs = notifs; - this.logs = logs; + this._logs = logs; } public void Start(BasePlugin parent) @@ -117,7 +117,7 @@ public bool MarkRebel(CCSPlayerController player, long time = 120) { if (!rebelTimes.ContainsKey(player)) { - logs.Append(player.PlayerName + " is now a rebel."); + _logs.Append(_logs.Player(player), "is now a rebel."); } rebelTimes[player] = DateTimeOffset.Now.ToUnixTimeSeconds() + time; @@ -128,13 +128,13 @@ public bool MarkRebel(CCSPlayerController player, long time = 120) public void UnmarkRebel(CCSPlayerController player) { notifs.NO_LONGER_REBEL.ToPlayerChat(player); - logs.Append(player.PlayerName + " is no longer a rebel."); + _logs.Append(_logs.Player(player), "is no longer a rebel."); rebelTimes.Remove(player); ApplyRebelColor(player); } - // https://www.desmos.com/calculator/g2v6vvg7ax + // https://www.desmos.com/calculator/g2v6vvg7ax private float GetRebelTimePercentage(CCSPlayerController player) { long x = GetRebelTimeLeft(player); @@ -178,4 +178,4 @@ private void SendTimeLeft(CCSPlayerController player) player.PrintToCenterHtml($"You are {formattedColor}rebelling"); } -} \ No newline at end of file +} diff --git a/mod/Jailbreak.Warden/Global/WardenBehavior.cs b/mod/Jailbreak.Warden/Global/WardenBehavior.cs index 05c05dbc..135e1ada 100644 --- a/mod/Jailbreak.Warden/Global/WardenBehavior.cs +++ b/mod/Jailbreak.Warden/Global/WardenBehavior.cs @@ -22,14 +22,14 @@ namespace Jailbreak.Warden.Global; public class WardenBehavior : IPluginBehavior, IWardenService { private ILogger _logger; - private ILogService logs; + private IRichLogService logs; private IWardenNotifications _notifications; private bool _hasWarden; private CCSPlayerController? _warden; - public WardenBehavior(ILogger logger, IWardenNotifications notifications, ILogService logs) + public WardenBehavior(ILogger logger, IWardenNotifications notifications, IRichLogService logs) { _logger = logger; _notifications = notifications; @@ -70,8 +70,8 @@ public bool TrySetWarden(CCSPlayerController controller) _notifications.NEW_WARDEN(_warden) .ToAllChat() .ToAllCenter(); - - logs.Append($"{_warden.PlayerName} is now the warden."); + + logs.Append( logs.Player(_warden), "is now the warden."); return true; } @@ -87,9 +87,9 @@ public bool TryRemoveWarden() _warden.Pawn.Value.RenderMode = RenderMode_t.kRenderTransColor; _warden.Pawn.Value.Render = Color.FromArgb(254, 255, 255, 255); Utilities.SetStateChanged(_warden.Pawn.Value, "CBaseModelEntity", "m_clrRender"); - logs.Append($"{_warden.PlayerName} is no longer the warden."); + logs.Append( logs.Player(_warden), "is no longer the warden."); } - + _warden = null; return true; diff --git a/public/Jailbreak.Formatting/Base/SimpleView.cs b/public/Jailbreak.Formatting/Base/SimpleView.cs index 48210e40..31b956f4 100644 --- a/public/Jailbreak.Formatting/Base/SimpleView.cs +++ b/public/Jailbreak.Formatting/Base/SimpleView.cs @@ -7,6 +7,13 @@ namespace Jailbreak.Formatting.Base; public class SimpleView : IView, IEnumerable> { + public struct Newline + { + + } + + public static Newline NEWLINE = new Newline(); + private List> _lines = new(); public SimpleView() @@ -28,13 +35,24 @@ public void Add(FormatObject item) } /// - /// Add a whole new row to this simpleview - /// Eg, { { 123 }, { abc }, { weeeeee } } are each their own lines. + /// Add multiple items at a time to this SimpleView /// /// public void Add(params FormatObject[] line) { - _lines.Add(new List(line)); + if (_lines.Count == 0) + _lines.Add(new List()); + + _lines[_lines.Count - 1].AddRange(line); + } + + /// + /// Add a new line to this SimpleView + /// + /// + public void Add(Newline newline) + { + _lines.Add(new List()); } public void Render(FormatWriter writer) diff --git a/public/Jailbreak.Formatting/Objects/TreeFormatObject.cs b/public/Jailbreak.Formatting/Objects/TreeFormatObject.cs new file mode 100644 index 00000000..cb616eb2 --- /dev/null +++ b/public/Jailbreak.Formatting/Objects/TreeFormatObject.cs @@ -0,0 +1,86 @@ +using System.Collections; + +using Jailbreak.Formatting.Core; + +namespace Jailbreak.Formatting.Objects; + +/// +/// Merges several FormatObjects into one. +/// This class will throw an error if any of it's descendant formatobjects are itself, +/// to prevent looping. +/// +public class TreeFormatObject : FormatObject, IEnumerable +{ + private List _children = new(); + + private int _locked = 0; + + public TreeFormatObject() + { + + } + + /// + /// Lock this object, execute callback, then unlock. + /// + /// + private T Lock(Func callback) + { + // Achieve a re-entrant mutex for this thread. + // We can re-enter this lock as long as we are in the same thread, but others are blocked. + // this allows us to do the internal increment safely. + lock (this) + { + // set _locked to 1 if value is 0 + int old = Interlocked.CompareExchange(ref _locked, 1, 0); + + if (old == 1) + throw new Exception("Possible loop detected in TreeFormatObject! Already locked during traversal"); + + var result = callback(); + _locked = 0; + + return result; + } + } + + public override string ToPlain() + { + return Lock(() => + { + var childPlain = _children.Select(child => child.ToPlain()); + return string.Join(' ', childPlain); + }); + } + + public override string ToChat() + { + return Lock(() => + { + var childChat = _children.Select(child => child.ToChat()); + return string.Join(' ', childChat); + }); + } + + public override string ToPanorama() + { + return Lock(() => + { + var childPanorama = _children.Select(child => child.ToPanorama()); + return string.Join(' ', childPanorama); + }); + } + + public void Add(FormatObject formatObject) + => _children.Add(formatObject); + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} diff --git a/public/Jailbreak.Formatting/Views/Logging/IRichLogService.cs b/public/Jailbreak.Formatting/Views/Logging/IRichLogService.cs new file mode 100644 index 00000000..05669315 --- /dev/null +++ b/public/Jailbreak.Formatting/Views/Logging/IRichLogService.cs @@ -0,0 +1,13 @@ +using CounterStrikeSharp.API.Core; + +using Jailbreak.Formatting.Core; +using Jailbreak.Public.Mod.Logs; + +namespace Jailbreak.Formatting.Views; + +public interface IRichLogService : ILogService +{ + void Append(params FormatObject[] objects); + + FormatObject Player(CCSPlayerController playerController); +} diff --git a/public/Jailbreak.Formatting/Views/IRichPlayerTag.cs b/public/Jailbreak.Formatting/Views/Logging/IRichPlayerTag.cs similarity index 81% rename from public/Jailbreak.Formatting/Views/IRichPlayerTag.cs rename to public/Jailbreak.Formatting/Views/Logging/IRichPlayerTag.cs index 0c14809a..ad4bab87 100644 --- a/public/Jailbreak.Formatting/Views/IRichPlayerTag.cs +++ b/public/Jailbreak.Formatting/Views/Logging/IRichPlayerTag.cs @@ -1,10 +1,11 @@ using CounterStrikeSharp.API.Core; using Jailbreak.Formatting.Core; +using Jailbreak.Public.Mod.Logs; namespace Jailbreak.Formatting.Views; -public interface IRichPlayerTag +public interface IRichPlayerTag : IPlayerTag { /// /// Get a tag for this player, which contains context about the player's current actions From 7318c55230183441f6d2ea4840abad84be550f8c Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:30:53 -0800 Subject: [PATCH 4/8] Fix build errors --- mod/Jailbreak.Teams/Queue/QueueBehavior.cs | 24 +++++++++---------- .../Commands/WardenCommandsBehavior.cs | 12 +++++----- .../Selection/WardenSelectionBehavior.cs | 6 ++--- .../Views/IRebelNotifications.cs | 4 ++-- .../Views/ITeamsNotifications.cs | 18 +++++++------- .../Views/IWardenNotifications.cs | 23 +++++++++--------- 6 files changed, 44 insertions(+), 43 deletions(-) diff --git a/mod/Jailbreak.Teams/Queue/QueueBehavior.cs b/mod/Jailbreak.Teams/Queue/QueueBehavior.cs index 64762765..e174183a 100644 --- a/mod/Jailbreak.Teams/Queue/QueueBehavior.cs +++ b/mod/Jailbreak.Teams/Queue/QueueBehavior.cs @@ -34,7 +34,7 @@ public bool TryEnterQueue(CCSPlayerController player) { if (!player.IsReal()) return false; - + if (player.GetTeam() == CsTeam.CounterTerrorist) return false; @@ -50,7 +50,7 @@ public bool TryExitQueue(CCSPlayerController player) { if (!player.IsReal()) return false; - + var state = _state.Get(player); state.InQueue = false; state.IsGuard = false; @@ -64,8 +64,8 @@ public bool TryPop(int count) if (queue.Count <= count) { - _notifications.NotEnoughGuards.ToAllChat(); - _notifications.PleaseJoinGuardQueue.ToAllChat().ToAllCenter(); + _notifications.NOT_ENOUGH_GUARDS.ToAllChat(); + _notifications.PLEASE_JOIN_GUARD_QUEUE.ToAllChat().ToAllCenter(); } _logger.LogInformation("[Queue] Pop requested {@Count} out of {@InQueue}", count, queue.Count); @@ -100,7 +100,7 @@ public bool TryPush(int count) TryEnterQueue(toSwap); - _notifications.YouWereAutobalancedPrisoner.ToPlayerCenter(toSwap); + _notifications.YOU_WERE_AUTOBALANCED_PRISONER.ToPlayerCenter(toSwap); } return true; @@ -111,7 +111,7 @@ public void ForceGuard(CCSPlayerController player) // Set IsGuard so they won't be swapped back. _state.Get(player).IsGuard = true; - _notifications.YouWereAutobalancedGuard + _notifications.YOU_WERE_AUTOBALANCED_GUARD .ToPlayerChat(player) .ToPlayerCenter(player); @@ -168,7 +168,7 @@ public HookResult OnRequestToJoinTeam(CCSPlayerController? invoked, CommandInfo // If so, stop them!! if ((CsTeam)team == CsTeam.CounterTerrorist && !state.IsGuard) { - _notifications.AttemptToJoinFromTeamMenu + _notifications.ATTEMPT_TO_JOIN_FROM_TEAM_MENU .ToPlayerChat(invoked) .ToPlayerCenter(invoked); @@ -196,7 +196,7 @@ public HookResult OnPlayerSpawn(EventPlayerSpawn ev, GameEventInfo info) if (player.GetTeam() == CsTeam.CounterTerrorist && !state.IsGuard) { - _notifications.AttemptToJoinFromTeamMenu + _notifications.ATTEMPT_TO_JOIN_FROM_TEAM_MENU .ToPlayerChat(player) .ToPlayerCenter(player); @@ -221,7 +221,7 @@ public HookResult OnPlayerTeam(EventPlayerTeam ev, GameEventInfo info) if ((CsTeam)ev.Team != CsTeam.CounterTerrorist && state.IsGuard) if (TryExitQueue(player)) - _notifications.LeftGuard + _notifications.LEFT_GUARD .ToPlayerCenter(player) .ToPlayerChat(player); @@ -231,7 +231,7 @@ public HookResult OnPlayerTeam(EventPlayerTeam ev, GameEventInfo info) private void HandleQueueRequest(CCSPlayerController player) { if (TryEnterQueue(player)) - _notifications.JoinedGuardQueue + _notifications.JOINED_GUARD_QUEUE .ToPlayerCenter(player) .ToPlayerChat(player); else @@ -241,7 +241,7 @@ private void HandleQueueRequest(CCSPlayerController player) private void HandleLeaveRequest(CCSPlayerController player) { if (TryExitQueue(player)) - _notifications.LeftGuard + _notifications.LEFT_GUARD .ToPlayerCenter(player) .ToPlayerChat(player); else @@ -266,4 +266,4 @@ public void Command_Leave(CCSPlayerController? player, CommandInfo command) return; HandleLeaveRequest(player); } -} \ No newline at end of file +} diff --git a/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs b/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs index 828f327a..64bc63ad 100644 --- a/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs +++ b/mod/Jailbreak.Warden/Commands/WardenCommandsBehavior.cs @@ -42,11 +42,11 @@ public void Command_Pass(CCSPlayerController? player, CommandInfo command) if (_warden.IsWarden(player)) { // Handle warden pass - _notifications.PassWarden(player) + _notifications.PASS_WARDEN(player) .ToAllChat() .ToAllCenter(); - _notifications.BecomeNextWarden.ToAllChat(); + _notifications.BECOME_NEXT_WARDEN.ToAllChat(); if (!_warden.TryRemoveWarden()) Server.PrintToChatAll("[BUG] Couldn't remove warden :^("); @@ -70,13 +70,13 @@ public void Command_Warden(CCSPlayerController? player, CommandInfo command) if (!_queue.InQueue(player)) { if (_queue.TryEnter(player)) - _notifications.JoinRaffle.ToPlayerChat(player); + _notifications.JOIN_RAFFLE.ToPlayerChat(player); return; } if (_queue.InQueue(player)) if (_queue.TryExit(player)) - _notifications.LeaveRaffle.ToPlayerChat(player); + _notifications.LEAVE_RAFFLE.ToPlayerChat(player); return; } @@ -85,6 +85,6 @@ public void Command_Warden(CCSPlayerController? player, CommandInfo command) if (isCt && !_warden.HasWarden) _warden.TrySetWarden(player); - _notifications.CurrentWarden(_warden.Warden).ToPlayerChat(player); + _notifications.CURRENT_WARDEN(_warden.Warden).ToPlayerChat(player); } -} \ No newline at end of file +} diff --git a/mod/Jailbreak.Warden/Selection/WardenSelectionBehavior.cs b/mod/Jailbreak.Warden/Selection/WardenSelectionBehavior.cs index ed4c7931..315a51d6 100644 --- a/mod/Jailbreak.Warden/Selection/WardenSelectionBehavior.cs +++ b/mod/Jailbreak.Warden/Selection/WardenSelectionBehavior.cs @@ -92,7 +92,7 @@ public HookResult OnRoundStart(EventRoundStart ev, GameEventInfo info) // Enable the warden queue _queueInactive = false; - _notifications.PickingShortly.ToAllChat(); + _notifications.PICKING_SHORTLY.ToAllChat(); // Start a timer to pick the warden in 7 seconds ScheduleChooseWarden(); @@ -121,7 +121,7 @@ protected void OnChooseWarden() if (eligible.Count == 0) { - _notifications.NoWardens.ToAllChat(); + _notifications.NO_WARDENS.ToAllChat(); _queueInactive = true; return; @@ -178,4 +178,4 @@ private bool CanEnterQueue(CCSPlayerController player) return true; } -} \ No newline at end of file +} diff --git a/public/Jailbreak.Formatting/Views/IRebelNotifications.cs b/public/Jailbreak.Formatting/Views/IRebelNotifications.cs index 53ec2027..26303309 100644 --- a/public/Jailbreak.Formatting/Views/IRebelNotifications.cs +++ b/public/Jailbreak.Formatting/Views/IRebelNotifications.cs @@ -4,5 +4,5 @@ namespace Jailbreak.Formatting.Views; public interface IRebelNotifications { - public IView NoLongerRebel { get; } -} \ No newline at end of file + public IView NO_LONGER_REBEL { get; } +} diff --git a/public/Jailbreak.Formatting/Views/ITeamsNotifications.cs b/public/Jailbreak.Formatting/Views/ITeamsNotifications.cs index e687431d..eb4a5880 100644 --- a/public/Jailbreak.Formatting/Views/ITeamsNotifications.cs +++ b/public/Jailbreak.Formatting/Views/ITeamsNotifications.cs @@ -4,20 +4,20 @@ namespace Jailbreak.Formatting.Views; public interface IRatioNotifications { - public IView NotEnoughGuards { get; } + public IView NOT_ENOUGH_GUARDS { get; } - public IView PleaseJoinGuardQueue { get; } + public IView PLEASE_JOIN_GUARD_QUEUE { get; } - public IView JoinedGuardQueue { get; } + public IView JOINED_GUARD_QUEUE { get; } - public IView AlreadyAGuard { get; } + public IView ALREADY_A_GUARD { get; } - public IView YouWereAutobalancedPrisoner { get; } + public IView YOU_WERE_AUTOBALANCED_PRISONER { get; } - public IView YouWereAutobalancedGuard { get; } + public IView YOU_WERE_AUTOBALANCED_GUARD { get; } - public IView AttemptToJoinFromTeamMenu { get; } + public IView ATTEMPT_TO_JOIN_FROM_TEAM_MENU { get; } - public IView LeftGuard { get; } -} \ No newline at end of file + public IView LEFT_GUARD { get; } +} diff --git a/public/Jailbreak.Formatting/Views/IWardenNotifications.cs b/public/Jailbreak.Formatting/Views/IWardenNotifications.cs index 5ccbffcd..36b7f465 100644 --- a/public/Jailbreak.Formatting/Views/IWardenNotifications.cs +++ b/public/Jailbreak.Formatting/Views/IWardenNotifications.cs @@ -1,31 +1,32 @@ using CounterStrikeSharp.API.Core; using Jailbreak.Formatting.Base; +// ReSharper disable InconsistentNaming namespace Jailbreak.Formatting.Views; public interface IWardenNotifications { - public IView PickingShortly { get; } - public IView NoWardens { get; } - public IView WardenLeft { get; } - public IView WardenDied { get; } - public IView BecomeNextWarden { get; } - public IView JoinRaffle { get; } - public IView LeaveRaffle { get; } + public IView PICKING_SHORTLY { get; } + public IView NO_WARDENS { get; } + public IView WARDEN_LEFT { get; } + public IView WARDEN_DIED { get; } + public IView BECOME_NEXT_WARDEN { get; } + public IView JOIN_RAFFLE { get; } + public IView LEAVE_RAFFLE { get; } /// /// Create a view for when the specified player passes warden /// /// /// - public IView PassWarden(CCSPlayerController player); + public IView PASS_WARDEN(CCSPlayerController player); /// /// Create a view for when this player becomes a new warden /// /// /// - public IView NewWarden(CCSPlayerController player); + public IView NEW_WARDEN(CCSPlayerController player); /// /// Format a response to a request about the current warden. @@ -33,5 +34,5 @@ public interface IWardenNotifications /// /// /// - public IView CurrentWarden(CCSPlayerController? player); -} \ No newline at end of file + public IView CURRENT_WARDEN(CCSPlayerController? player); +} From 869a66a1cc582df54eb99c26b92db5d8651882dc Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Tue, 6 Feb 2024 11:59:43 -0800 Subject: [PATCH 5/8] Refactor entity I/O listener, add func_breakable IO listener * TODO: IO listener will only listen for when the breakable does something when it breaks... We need a better way to listen for eg. CTs pursuing vents. --- .../Listeners/LogEntityListeners.cs | 29 +++++++++++------ .../Extensions/EntityIOExtensions.cs | 31 +++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 public/Jailbreak.Public/Extensions/EntityIOExtensions.cs diff --git a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs index c2c7fe8a..0bfc2c70 100644 --- a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs +++ b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs @@ -4,6 +4,7 @@ using Jailbreak.Formatting.Views; using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Extensions; namespace Jailbreak.Logs; @@ -20,19 +21,29 @@ public LogEntityListeners(IRichLogService logs) public HookResult OnButtonPressed(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay) { - if (!activator.IsValid) - return HookResult.Continue; - int index = (int)activator.Index; - CCSPlayerPawn? pawn = Utilities.GetEntityFromIndex(index); - if (!pawn.IsValid) - return HookResult.Continue; - if (!pawn.OriginalController.IsValid) + if (!activator.TryGetController(out var player)) return HookResult.Continue; + CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); - if (!ent.IsValid) + + + _logs.Append( + $"{_logs.Player(player)} pressed a button: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); + return HookResult.Continue; + } + + [EntityOutputHook("func_breakable", "OnBreak")] + public HookResult OnBreakableBroken(CEntityIOOutput output, string name, CEntityInstance activator, + CEntityInstance caller, CVariant value, float delay) + { + if (!activator.TryGetController(out var player)) return HookResult.Continue; + + CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); + + _logs.Append( - $"{_logs.Player(pawn.OriginalController.Value!)} pressed a button {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); + $"{_logs.Player(player)} broke an entity: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); return HookResult.Continue; } } diff --git a/public/Jailbreak.Public/Extensions/EntityIOExtensions.cs b/public/Jailbreak.Public/Extensions/EntityIOExtensions.cs new file mode 100644 index 00000000..c4c5b6d7 --- /dev/null +++ b/public/Jailbreak.Public/Extensions/EntityIOExtensions.cs @@ -0,0 +1,31 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; + +namespace Jailbreak.Public.Extensions; + +public static class EntityIOExtensions +{ + public static bool TryGetController(this CEntityInstance pawn, out CCSPlayerController? controller) + { + controller = null; + + if (!pawn.IsValid) + return false; + + int index = (int)pawn.Index; + var playerPawn = Utilities.GetEntityFromIndex(index); + + if (!playerPawn.IsValid) + return false; + + if (!playerPawn.OriginalController.IsValid) + return false; + + controller = playerPawn.OriginalController.Value; + + if (controller?.IsReal() != true) + return false; + + return true; + } +} From 236784d79312e584fb5b85419ea5b56e8eae4924 Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Tue, 6 Feb 2024 12:35:15 -0800 Subject: [PATCH 6/8] Fix entity log formatting, prevent issues with invalid player handles in PlayerFormatObject --- mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs | 6 ++---- public/Jailbreak.Formatting/Core/FormatObject.cs | 5 ++++- .../Objects/PlayerFormatObject.cs | 12 ++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs index 0bfc2c70..87991aaf 100644 --- a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs +++ b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs @@ -27,8 +27,7 @@ public HookResult OnButtonPressed(CEntityIOOutput output, string name, CEntityIn CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); - _logs.Append( - $"{_logs.Player(player)} pressed a button: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); + _logs.Append(_logs.Player(player) $"pressed a button: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); return HookResult.Continue; } @@ -42,8 +41,7 @@ public HookResult OnBreakableBroken(CEntityIOOutput output, string name, CEntity CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); - _logs.Append( - $"{_logs.Player(player)} broke an entity: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); + _logs.Append(_logs.Player(player), $"broke an entity: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); return HookResult.Continue; } } diff --git a/public/Jailbreak.Formatting/Core/FormatObject.cs b/public/Jailbreak.Formatting/Core/FormatObject.cs index daef6232..9bbddc1b 100644 --- a/public/Jailbreak.Formatting/Core/FormatObject.cs +++ b/public/Jailbreak.Formatting/Core/FormatObject.cs @@ -45,4 +45,7 @@ public static FormatObject FromObject(object value) { return new StringFormatObject(value.ToString() ?? "null"); } -} \ No newline at end of file + + public override string ToString() + => ToPlain(); +} diff --git a/public/Jailbreak.Formatting/Objects/PlayerFormatObject.cs b/public/Jailbreak.Formatting/Objects/PlayerFormatObject.cs index 08b04f0e..3143fecf 100644 --- a/public/Jailbreak.Formatting/Objects/PlayerFormatObject.cs +++ b/public/Jailbreak.Formatting/Objects/PlayerFormatObject.cs @@ -7,25 +7,25 @@ namespace Jailbreak.Formatting.Objects; public class PlayerFormatObject : FormatObject { - private readonly CCSPlayerController _player; + private readonly string _name; public PlayerFormatObject(CCSPlayerController player) { - _player = player; + _name = player.PlayerName; } public override string ToChat() { - return $"{ChatColors.Yellow}{_player.PlayerName}"; + return $"{ChatColors.Yellow}{_name}"; } public override string ToPanorama() { - return _player.PlayerName.Sanitize(); + return _name.Sanitize(); } public override string ToPlain() { - return _player.PlayerName; + return _name; } -} \ No newline at end of file +} From 538f64e3b7f08e73832010eae4e3c4c150112922 Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+Mooshua@users.noreply.github.com> Date: Tue, 6 Feb 2024 12:49:32 -0800 Subject: [PATCH 7/8] Update namespaces, fix syntax error (whoops) --- mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs | 6 ++---- mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs | 4 ++-- mod/Jailbreak.Logs/LogsServiceExtension.cs | 1 + 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs b/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs index db78ec07..e0f1b658 100644 --- a/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs +++ b/mod/Jailbreak.Logs/Listeners/LogDamageListeners.cs @@ -1,13 +1,11 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using Jailbreak.Formatting.Views; using Jailbreak.Public.Behaviors; using Jailbreak.Public.Extensions; -using Jailbreak.Public.Mod.Logs; -namespace Jailbreak.Logs; +namespace Jailbreak.Logs.Listeners; public class LogDamageListeners : IPluginBehavior { diff --git a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs index 87991aaf..22f51286 100644 --- a/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs +++ b/mod/Jailbreak.Logs/Listeners/LogEntityListeners.cs @@ -6,7 +6,7 @@ using Jailbreak.Public.Behaviors; using Jailbreak.Public.Extensions; -namespace Jailbreak.Logs; +namespace Jailbreak.Logs.Listeners; public class LogEntityListeners : IPluginBehavior { @@ -27,7 +27,7 @@ public HookResult OnButtonPressed(CEntityIOOutput output, string name, CEntityIn CBaseEntity? ent = Utilities.GetEntityFromIndex((int)caller.Index); - _logs.Append(_logs.Player(player) $"pressed a button: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); + _logs.Append(_logs.Player(player), $"pressed a button: {ent.Entity?.Name ?? "Unlabeled"} -> {output?.Connections?.TargetDesc ?? "None"}"); return HookResult.Continue; } diff --git a/mod/Jailbreak.Logs/LogsServiceExtension.cs b/mod/Jailbreak.Logs/LogsServiceExtension.cs index 71e203ac..6918ea04 100644 --- a/mod/Jailbreak.Logs/LogsServiceExtension.cs +++ b/mod/Jailbreak.Logs/LogsServiceExtension.cs @@ -1,4 +1,5 @@ using Jailbreak.Formatting.Views; +using Jailbreak.Logs.Listeners; using Jailbreak.Logs.Tags; using Jailbreak.Public.Extensions; using Jailbreak.Public.Mod.Logs; From c5132ec96f07bf4192027052fb26724bb074dcbf Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+mooshua@users.noreply.github.com> Date: Tue, 6 Feb 2024 12:50:02 -0800 Subject: [PATCH 8/8] Add downloads to README.md --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5274d75d..0ef7da8e 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,17 @@ The classic Jail gamemode, ported to Counter-Strike 2. -> [!WARNING] -> This plugin is in active development and may cause server crashes or stability issues. +## Downloads + +[![Release](https://img.shields.io/badge/Release-mediumseagreen?style=for-the-badge&logo=onlyoffice +)](https://github.com/edgegamers/Jailbreak/releases/)⠀⠀ +[![Stable](https://img.shields.io/badge/Stable-orangered?style=for-the-badge&logo=onlyoffice)](https://nightly.link/edgegamers/Jailbreak/workflows/nightly/main/jailbreak-nightly)⠀⠀ +[![Dev](https://img.shields.io/badge/Nightly-slateblue?style=for-the-badge&logo=onlyoffice +)](https://nightly.link/edgegamers/Jailbreak/workflows/nightly/dev/jailbreak-nightly) + +**Release** builds are our full releases. We try to keep these high-quality and bug-free, when we can. +Our **Stable** builds run on EdgeGamers' own Jailbreak servers. +Our **Nightly** builds are used exclusively for development and staging, and are likely to have problems. ## Status