From 4462e09640cfa59a5f89746192cce739796d8d4b Mon Sep 17 00:00:00 2001 From: Extremelyd1 <10898310+Extremelyd1@users.noreply.github.com> Date: Sat, 23 May 2026 23:31:38 +0200 Subject: [PATCH 1/2] Refactor dispatching of packet handlers to interface to remove dependency on Unity in server context --- .../Packet/PacketHandlerRegistry.cs | 46 ++++++++++++++----- SSMP/Networking/Packet/PacketManager.cs | 12 ++--- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/SSMP/Networking/Packet/PacketHandlerRegistry.cs b/SSMP/Networking/Packet/PacketHandlerRegistry.cs index 280618e2..270c3eb7 100644 --- a/SSMP/Networking/Packet/PacketHandlerRegistry.cs +++ b/SSMP/Networking/Packet/PacketHandlerRegistry.cs @@ -21,10 +21,13 @@ internal class PacketHandlerRegistry private readonly Dictionary _handlers = new(); /// - /// Whether to dispatch handler invocations to the Unity main thread. - /// Client handlers typically need main thread dispatch; server handlers do not. + /// The dispatcher that handles how to call the packet handlers. + /// For clients, this will be the , which invokes packet + /// handlers on the Unity main thread. + /// For servers, this will be the , which directly invokes the + /// packet handlers. /// - private readonly bool _dispatchToMainThread; + private readonly IPacketHandlerRegistryDispatcher _dispatcher; /// /// Descriptive name for logging messages. @@ -35,10 +38,10 @@ internal class PacketHandlerRegistry /// Constructs a new packet handler registry. /// /// Name for logging purposes (e.g., "client update", "server connection"). - /// Whether to dispatch handler calls to Unity main thread. - public PacketHandlerRegistry(string registryName, bool dispatchToMainThread) { + /// The dispatcher that handles how to call the packet handlers. + public PacketHandlerRegistry(string registryName, IPacketHandlerRegistryDispatcher dispatcher) { _registryName = registryName; - _dispatchToMainThread = dispatchToMainThread; + _dispatcher = dispatcher; } /// @@ -77,11 +80,7 @@ public void Execute(TPacketId packetId, Action invoker) { return; } - if (_dispatchToMainThread) { - ThreadUtil.RunActionOnMainThread(() => SafeInvoke(packetId, handler, invoker)); - } else { - SafeInvoke(packetId, handler, invoker); - } + _dispatcher.Dispatch(() => SafeInvoke(packetId, handler, invoker)); } /// @@ -95,3 +94,28 @@ private void SafeInvoke(TPacketId packetId, THandler handler, Action i } } } + +/// +/// Interface for packet handler dispatchers. +/// +internal interface IPacketHandlerRegistryDispatcher { + void Dispatch(Action action); +} + +/// +/// Implementation of packet handler dispatcher to immediately invoke the handler directly for the server-side. +/// +internal class ServerPacketHandlerRegistryDispatcher : IPacketHandlerRegistryDispatcher { + public void Dispatch(Action action) { + action.Invoke(); + } +} + +/// +/// Implementation of packet handler dispatcher to invoke the handler on Unity's main thread. +/// +internal class ClientPacketHandlerRegistryDispatcher : IPacketHandlerRegistryDispatcher { + public void Dispatch(Action action) { + ThreadUtil.RunActionOnMainThread(action); + } +} diff --git a/SSMP/Networking/Packet/PacketManager.cs b/SSMP/Networking/Packet/PacketManager.cs index 0ca65ed1..679f6811 100644 --- a/SSMP/Networking/Packet/PacketManager.cs +++ b/SSMP/Networking/Packet/PacketManager.cs @@ -43,16 +43,16 @@ internal class PacketManager { #region Standard Packet Registries private readonly PacketHandlerRegistry _clientUpdateRegistry = new( - "client update", true + "client update", new ClientPacketHandlerRegistryDispatcher() ); private readonly PacketHandlerRegistry _clientConnectionRegistry = new( - "client connection", true + "client connection", new ClientPacketHandlerRegistryDispatcher() ); private readonly PacketHandlerRegistry _serverUpdateRegistry = new( - "server update", false + "server update", new ServerPacketHandlerRegistryDispatcher() ); private readonly PacketHandlerRegistry _serverConnectionRegistry = new( - "server connection", false + "server connection", new ServerPacketHandlerRegistryDispatcher() ); #endregion @@ -268,7 +268,7 @@ string nameType ) { if (!registryDict.TryGetValue(addonId, out var registry)) { registry = new PacketHandlerRegistry( - $"client addon {nameType} (Addon {addonId})", true + $"client addon {nameType} (Addon {addonId})", new ClientPacketHandlerRegistryDispatcher() ); registryDict[addonId] = registry; } @@ -323,7 +323,7 @@ string nameType ) { if (!registryDict.TryGetValue(addonId, out var registry)) { registry = new PacketHandlerRegistry( - $"server addon {nameType} (Addon {addonId})", false + $"server addon {nameType} (Addon {addonId})", new ServerPacketHandlerRegistryDispatcher() ); registryDict[addonId] = registry; } From 57f584f32b2f9336cb9bea6a11abb1d5706b2c58 Mon Sep 17 00:00:00 2001 From: Extremelyd1 <10898310+Extremelyd1@users.noreply.github.com> Date: Sat, 30 May 2026 09:51:29 +0200 Subject: [PATCH 2/2] Make dispatchers singleton --- .../Packet/PacketHandlerRegistry.cs | 27 +++++++++++++++++++ SSMP/Networking/Packet/PacketManager.cs | 12 ++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/SSMP/Networking/Packet/PacketHandlerRegistry.cs b/SSMP/Networking/Packet/PacketHandlerRegistry.cs index 270c3eb7..9ccd534b 100644 --- a/SSMP/Networking/Packet/PacketHandlerRegistry.cs +++ b/SSMP/Networking/Packet/PacketHandlerRegistry.cs @@ -99,6 +99,9 @@ private void SafeInvoke(TPacketId packetId, THandler handler, Action i /// Interface for packet handler dispatchers. /// internal interface IPacketHandlerRegistryDispatcher { + /// + /// Dispatch this handler with the given action. + /// void Dispatch(Action action); } @@ -106,6 +109,18 @@ internal interface IPacketHandlerRegistryDispatcher { /// Implementation of packet handler dispatcher to immediately invoke the handler directly for the server-side. /// internal class ServerPacketHandlerRegistryDispatcher : IPacketHandlerRegistryDispatcher { + /// + /// Publicly accessible static instance, since instances can not vary. + /// + public static readonly ServerPacketHandlerRegistryDispatcher Instance = new(); + + /// + /// Private constructor to prevent access outside of static instance. + /// + private ServerPacketHandlerRegistryDispatcher() { + } + + /// public void Dispatch(Action action) { action.Invoke(); } @@ -115,6 +130,18 @@ public void Dispatch(Action action) { /// Implementation of packet handler dispatcher to invoke the handler on Unity's main thread. /// internal class ClientPacketHandlerRegistryDispatcher : IPacketHandlerRegistryDispatcher { + /// + /// Publicly accessible static instance, since instances can not vary. + /// + public static readonly ClientPacketHandlerRegistryDispatcher Instance = new(); + + /// + /// Private constructor to prevent access outside of static instance. + /// + private ClientPacketHandlerRegistryDispatcher() { + } + + /// public void Dispatch(Action action) { ThreadUtil.RunActionOnMainThread(action); } diff --git a/SSMP/Networking/Packet/PacketManager.cs b/SSMP/Networking/Packet/PacketManager.cs index 679f6811..f590702c 100644 --- a/SSMP/Networking/Packet/PacketManager.cs +++ b/SSMP/Networking/Packet/PacketManager.cs @@ -43,16 +43,16 @@ internal class PacketManager { #region Standard Packet Registries private readonly PacketHandlerRegistry _clientUpdateRegistry = new( - "client update", new ClientPacketHandlerRegistryDispatcher() + "client update", ClientPacketHandlerRegistryDispatcher.Instance ); private readonly PacketHandlerRegistry _clientConnectionRegistry = new( - "client connection", new ClientPacketHandlerRegistryDispatcher() + "client connection", ClientPacketHandlerRegistryDispatcher.Instance ); private readonly PacketHandlerRegistry _serverUpdateRegistry = new( - "server update", new ServerPacketHandlerRegistryDispatcher() + "server update", ServerPacketHandlerRegistryDispatcher.Instance ); private readonly PacketHandlerRegistry _serverConnectionRegistry = new( - "server connection", new ServerPacketHandlerRegistryDispatcher() + "server connection", ServerPacketHandlerRegistryDispatcher.Instance ); #endregion @@ -268,7 +268,7 @@ string nameType ) { if (!registryDict.TryGetValue(addonId, out var registry)) { registry = new PacketHandlerRegistry( - $"client addon {nameType} (Addon {addonId})", new ClientPacketHandlerRegistryDispatcher() + $"client addon {nameType} (Addon {addonId})", ClientPacketHandlerRegistryDispatcher.Instance ); registryDict[addonId] = registry; } @@ -323,7 +323,7 @@ string nameType ) { if (!registryDict.TryGetValue(addonId, out var registry)) { registry = new PacketHandlerRegistry( - $"server addon {nameType} (Addon {addonId})", new ServerPacketHandlerRegistryDispatcher() + $"server addon {nameType} (Addon {addonId})", ServerPacketHandlerRegistryDispatcher.Instance ); registryDict[addonId] = registry; }