From 7e1a9019305de196cbe97fe7bb6bf5db052ec0ab Mon Sep 17 00:00:00 2001 From: dplochcoder Date: Sun, 10 Aug 2025 22:17:54 -0400 Subject: [PATCH 1/5] Allow clients to react to HKMP's time scale changes --- HKMP/Api/Client/IClientManager.cs | 10 ++++++++++ HKMP/Game/Client/ClientManager.cs | 16 +++++++++++++--- HKMP/Game/Client/PauseManager.cs | 15 ++++++++++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/HKMP/Api/Client/IClientManager.cs b/HKMP/Api/Client/IClientManager.cs index 53ed9f15..9d84272b 100644 --- a/HKMP/Api/Client/IClientManager.cs +++ b/HKMP/Api/Client/IClientManager.cs @@ -90,4 +90,14 @@ public interface IClientManager { /// Event that is called when another player leaves the local scene. /// event Action PlayerLeaveSceneEvent; + + /// + /// Event that is called when HKMP modifies the game's time scale. + /// + delegate void SetTimeScale(ref float timeScale); + + /// + /// Event that is called when HKMP modifies the game's time scale. + /// + event SetTimeScale OnSetTimeScale; } diff --git a/HKMP/Game/Client/ClientManager.cs b/HKMP/Game/Client/ClientManager.cs index 6ac6a69c..cc048088 100644 --- a/HKMP/Game/Client/ClientManager.cs +++ b/HKMP/Game/Client/ClientManager.cs @@ -74,6 +74,11 @@ internal class ClientManager : IClientManager { /// private readonly EntityManager _entityManager; + /// + /// The pause manager instance. + /// + private readonly PauseManager _pauseManager; + /// /// The client addon manager instance. /// @@ -128,6 +133,9 @@ public string Username { /// public event Action PlayerLeaveSceneEvent; + /// + public event IClientManager.SetTimeScale OnSetTimeScale; + /// public Team Team => _playerManager.LocalPlayerTeam; @@ -180,7 +188,9 @@ ModSettings modSettings _entityManager = new EntityManager(netClient); - new PauseManager(netClient).RegisterHooks(); + _pauseManager = new PauseManager(netClient, (ref float timeScale) => OnSetTimeScale?.Invoke(ref timeScale)); + _pauseManager.RegisterHooks(); + new FsmPatcher().RegisterHooks(); _commandManager = new ClientCommandManager(); @@ -327,7 +337,7 @@ private void InternalDisconnect() { // Check whether the game is in the pause menu and reset timescale to 0 in that case if (UIManager.instance.uiState.Equals(UIState.PAUSED)) { - PauseManager.SetTimeScale(0); + _pauseManager.SetTimeScale(0); } try { @@ -485,7 +495,7 @@ private void OnClientConnect(LoginResponse loginResponse) { // Since we are probably in the pause menu when we connect, set the timescale so the game // is running while paused - PauseManager.SetTimeScale(1.0f); + _pauseManager.SetTimeScale(1.0f); UiManager.InternalChatBox.AddMessage("You are connected to the server"); } diff --git a/HKMP/Game/Client/PauseManager.cs b/HKMP/Game/Client/PauseManager.cs index 89fda0fe..da50ddc1 100644 --- a/HKMP/Game/Client/PauseManager.cs +++ b/HKMP/Game/Client/PauseManager.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Reflection; using GlobalEnums; +using Hkmp.Api.Client; using Hkmp.Networking.Client; using Modding; using UnityEngine; @@ -15,9 +16,15 @@ internal class PauseManager { /// The net client instance. /// private readonly NetClient _netClient; + + /// + /// Hook for time scale changes. + /// + private readonly IClientManager.SetTimeScale _onSetTimeScale; - public PauseManager(NetClient netClient) { + public PauseManager(NetClient netClient, IClientManager.SetTimeScale onSetTimeScale) { _netClient = netClient; + _onSetTimeScale = onSetTimeScale; } /// @@ -194,7 +201,9 @@ private static void ImmediateUnpauseIfPaused() { /// Sets the time scale similarly to the method GameManager#SetTimeScale. /// /// The new time scale. - public static void SetTimeScale(float timeScale) { - TimeController.GenericTimeScale = timeScale > 0.00999999977648258 ? timeScale : 0.0f; + public void SetTimeScale(float timeScale) { + timeScale = timeScale > 0.00999999977648258 ? timeScale : 0.0f; + _onSetTimeScale(ref timeScale); + TimeController.GenericTimeScale = timeScale; } } From bd679558f969cfa18adae0adcb1ef078e63d6d62 Mon Sep 17 00:00:00 2001 From: dplochcoder Date: Mon, 11 Aug 2025 00:01:05 -0400 Subject: [PATCH 2/5] Make time scale hooks readonly --- HKMP/Api/Client/IClientManager.cs | 2 +- HKMP/Game/Client/ClientManager.cs | 2 +- HKMP/Game/Client/PauseManager.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HKMP/Api/Client/IClientManager.cs b/HKMP/Api/Client/IClientManager.cs index 9d84272b..18805b51 100644 --- a/HKMP/Api/Client/IClientManager.cs +++ b/HKMP/Api/Client/IClientManager.cs @@ -94,7 +94,7 @@ public interface IClientManager { /// /// Event that is called when HKMP modifies the game's time scale. /// - delegate void SetTimeScale(ref float timeScale); + delegate void SetTimeScale(float timeScale); /// /// Event that is called when HKMP modifies the game's time scale. diff --git a/HKMP/Game/Client/ClientManager.cs b/HKMP/Game/Client/ClientManager.cs index cc048088..f5bdc98d 100644 --- a/HKMP/Game/Client/ClientManager.cs +++ b/HKMP/Game/Client/ClientManager.cs @@ -188,7 +188,7 @@ ModSettings modSettings _entityManager = new EntityManager(netClient); - _pauseManager = new PauseManager(netClient, (ref float timeScale) => OnSetTimeScale?.Invoke(ref timeScale)); + _pauseManager = new PauseManager(netClient, timeScale => OnSetTimeScale?.Invoke(timeScale)); _pauseManager.RegisterHooks(); new FsmPatcher().RegisterHooks(); diff --git a/HKMP/Game/Client/PauseManager.cs b/HKMP/Game/Client/PauseManager.cs index da50ddc1..cab60a9b 100644 --- a/HKMP/Game/Client/PauseManager.cs +++ b/HKMP/Game/Client/PauseManager.cs @@ -203,7 +203,7 @@ private static void ImmediateUnpauseIfPaused() { /// The new time scale. public void SetTimeScale(float timeScale) { timeScale = timeScale > 0.00999999977648258 ? timeScale : 0.0f; - _onSetTimeScale(ref timeScale); TimeController.GenericTimeScale = timeScale; + _onSetTimeScale(timeScale); } } From f748587d8d0e302089cbbb7bd18a27a5ec1a75da Mon Sep 17 00:00:00 2001 From: dplochcoder Date: Wed, 13 Aug 2025 20:26:44 -0400 Subject: [PATCH 3/5] Allow loading multiple addons from a single dll --- HKMP/Api/Addon/AddonLoader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/HKMP/Api/Addon/AddonLoader.cs b/HKMP/Api/Addon/AddonLoader.cs index 420983ec..7e4b951a 100644 --- a/HKMP/Api/Addon/AddonLoader.cs +++ b/HKMP/Api/Addon/AddonLoader.cs @@ -96,8 +96,6 @@ protected List LoadAddons() { } addons.Add(addon); - // We only allow a single class extending the addon subclass - break; } } From fb30a9d0f10912e8cd533a45347989c387580802 Mon Sep 17 00:00:00 2001 From: dplochcoder Date: Tue, 16 Sep 2025 12:46:14 -0400 Subject: [PATCH 4/5] Address review comments --- HKMP/Api/Client/IClientManager.cs | 7 +------ HKMP/Game/Client/ClientManager.cs | 4 ++-- HKMP/Game/Client/PauseManager.cs | 6 +++--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/HKMP/Api/Client/IClientManager.cs b/HKMP/Api/Client/IClientManager.cs index 18805b51..e351e7f0 100644 --- a/HKMP/Api/Client/IClientManager.cs +++ b/HKMP/Api/Client/IClientManager.cs @@ -94,10 +94,5 @@ public interface IClientManager { /// /// Event that is called when HKMP modifies the game's time scale. /// - delegate void SetTimeScale(float timeScale); - - /// - /// Event that is called when HKMP modifies the game's time scale. - /// - event SetTimeScale OnSetTimeScale; + event Action SetTimeScaleEvent; } diff --git a/HKMP/Game/Client/ClientManager.cs b/HKMP/Game/Client/ClientManager.cs index f5bdc98d..a6330c18 100644 --- a/HKMP/Game/Client/ClientManager.cs +++ b/HKMP/Game/Client/ClientManager.cs @@ -134,7 +134,7 @@ public string Username { public event Action PlayerLeaveSceneEvent; /// - public event IClientManager.SetTimeScale OnSetTimeScale; + public event Action SetTimeScaleEvent; /// public Team Team => _playerManager.LocalPlayerTeam; @@ -188,7 +188,7 @@ ModSettings modSettings _entityManager = new EntityManager(netClient); - _pauseManager = new PauseManager(netClient, timeScale => OnSetTimeScale?.Invoke(timeScale)); + _pauseManager = new PauseManager(netClient, timeScale => SetTimeScaleEvent?.Invoke(timeScale)); _pauseManager.RegisterHooks(); new FsmPatcher().RegisterHooks(); diff --git a/HKMP/Game/Client/PauseManager.cs b/HKMP/Game/Client/PauseManager.cs index cab60a9b..3b6a95d1 100644 --- a/HKMP/Game/Client/PauseManager.cs +++ b/HKMP/Game/Client/PauseManager.cs @@ -1,7 +1,7 @@ +using System; using System.Collections; using System.Reflection; using GlobalEnums; -using Hkmp.Api.Client; using Hkmp.Networking.Client; using Modding; using UnityEngine; @@ -20,9 +20,9 @@ internal class PauseManager { /// /// Hook for time scale changes. /// - private readonly IClientManager.SetTimeScale _onSetTimeScale; + private readonly Action _onSetTimeScale; - public PauseManager(NetClient netClient, IClientManager.SetTimeScale onSetTimeScale) { + public PauseManager(NetClient netClient, Action onSetTimeScale) { _netClient = netClient; _onSetTimeScale = onSetTimeScale; } From b046a2dc1a8c74af926ecd456e1022dc8832eaf1 Mon Sep 17 00:00:00 2001 From: Extremelyd1 <10898310+Extremelyd1@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:32:53 +0200 Subject: [PATCH 5/5] Create PauseManager interface for API and move event there --- HKMP/Api/Client/IClientManager.cs | 12 ++++++------ HKMP/Api/Client/IPauseManager.cs | 13 +++++++++++++ HKMP/Game/Client/ClientManager.cs | 8 ++++---- HKMP/Game/Client/PauseManager.cs | 14 ++++++-------- 4 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 HKMP/Api/Client/IPauseManager.cs diff --git a/HKMP/Api/Client/IClientManager.cs b/HKMP/Api/Client/IClientManager.cs index e351e7f0..5b8e1e01 100644 --- a/HKMP/Api/Client/IClientManager.cs +++ b/HKMP/Api/Client/IClientManager.cs @@ -12,7 +12,12 @@ public interface IClientManager { /// Class that manages player locations on the in-game map. /// IMapManager MapManager { get; } - + + /// + /// Class that manages pause-related operations. + /// + IPauseManager PauseManager { get; } + /// /// The current username of the local player. /// @@ -90,9 +95,4 @@ public interface IClientManager { /// Event that is called when another player leaves the local scene. /// event Action PlayerLeaveSceneEvent; - - /// - /// Event that is called when HKMP modifies the game's time scale. - /// - event Action SetTimeScaleEvent; } diff --git a/HKMP/Api/Client/IPauseManager.cs b/HKMP/Api/Client/IPauseManager.cs new file mode 100644 index 00000000..e446a2c7 --- /dev/null +++ b/HKMP/Api/Client/IPauseManager.cs @@ -0,0 +1,13 @@ +using System; + +namespace Hkmp.Api.Client; + +/// +/// Client-side class that handles pause-related operations. +/// +public interface IPauseManager { + /// + /// Event that is called when HKMP modifies the game's timescale. + /// + event Action SetTimeScaleEvent; +} diff --git a/HKMP/Game/Client/ClientManager.cs b/HKMP/Game/Client/ClientManager.cs index a6330c18..c498aeb9 100644 --- a/HKMP/Game/Client/ClientManager.cs +++ b/HKMP/Game/Client/ClientManager.cs @@ -101,6 +101,9 @@ internal class ClientManager : IClientManager { /// public IMapManager MapManager => _mapManager; + /// + public IPauseManager PauseManager => _pauseManager; + /// public string Username { get { @@ -133,9 +136,6 @@ public string Username { /// public event Action PlayerLeaveSceneEvent; - /// - public event Action SetTimeScaleEvent; - /// public Team Team => _playerManager.LocalPlayerTeam; @@ -188,7 +188,7 @@ ModSettings modSettings _entityManager = new EntityManager(netClient); - _pauseManager = new PauseManager(netClient, timeScale => SetTimeScaleEvent?.Invoke(timeScale)); + _pauseManager = new PauseManager(netClient); _pauseManager.RegisterHooks(); new FsmPatcher().RegisterHooks(); diff --git a/HKMP/Game/Client/PauseManager.cs b/HKMP/Game/Client/PauseManager.cs index 3b6a95d1..f268eb02 100644 --- a/HKMP/Game/Client/PauseManager.cs +++ b/HKMP/Game/Client/PauseManager.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Reflection; using GlobalEnums; +using Hkmp.Api.Client; using Hkmp.Networking.Client; using Modding; using UnityEngine; @@ -11,20 +12,17 @@ namespace Hkmp.Game.Client; /// /// Handles pause related things to prevent player being invincible in pause menu while connected to a server. /// -internal class PauseManager { +internal class PauseManager : IPauseManager { /// /// The net client instance. /// private readonly NetClient _netClient; - /// - /// Hook for time scale changes. - /// - private readonly Action _onSetTimeScale; + /// + public event Action SetTimeScaleEvent; - public PauseManager(NetClient netClient, Action onSetTimeScale) { + public PauseManager(NetClient netClient) { _netClient = netClient; - _onSetTimeScale = onSetTimeScale; } /// @@ -204,6 +202,6 @@ private static void ImmediateUnpauseIfPaused() { public void SetTimeScale(float timeScale) { timeScale = timeScale > 0.00999999977648258 ? timeScale : 0.0f; TimeController.GenericTimeScale = timeScale; - _onSetTimeScale(timeScale); + SetTimeScaleEvent?.Invoke(timeScale); } }