diff --git a/Boot.Codes.csproj b/Boot.Codes.csproj index e6ef88e..dae6b58 100644 --- a/Boot.Codes.csproj +++ b/Boot.Codes.csproj @@ -7,8 +7,9 @@ - - + + + diff --git a/BootCodesPlugin.cs b/BootCodesPlugin.cs index aa41c9c..5140279 100644 --- a/BootCodesPlugin.cs +++ b/BootCodesPlugin.cs @@ -1,4 +1,6 @@ using System.Threading.Tasks; +using Boot.Codes.Handlers; +using Impostor.Api.Events.Managers; using Impostor.Api.Plugins; using Microsoft.Extensions.Logging; @@ -11,10 +13,11 @@ public class BootCodesPlugin : PluginBase private readonly IGameCodeManager _manager; - public BootCodesPlugin(ILogger logger, IGameCodeManager manager) + public BootCodesPlugin(ILogger logger, IGameCodeManager manager, IEventManager eventManager, GameEventListener eventListener) { this._logger = logger; this._manager = manager; + eventManager.RegisterListener(eventListener); } public override ValueTask EnableAsync() diff --git a/BootCodesPluginStartup.cs b/BootCodesPluginStartup.cs index 9486f92..6c0a75c 100644 --- a/BootCodesPluginStartup.cs +++ b/BootCodesPluginStartup.cs @@ -1,6 +1,7 @@ using Impostor.Api.Plugins; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.DependencyInjection; +using Boot.Codes.Handlers; namespace Boot.Codes { @@ -11,6 +12,7 @@ public void ConfigureHost(IHostBuilder host) { } public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); + services.AddSingleton(); } } } diff --git a/GameCodeManager.cs b/GameCodeManager.cs index 281e8b9..d871368 100644 --- a/GameCodeManager.cs +++ b/GameCodeManager.cs @@ -46,8 +46,6 @@ public GameCodeManager(ILogger logger, IGameCodeFactory codeFac this._codes = validCodes; this._inUse = new HashSet(); - - eventManager.RegisterListener(new GameEventListener(this)); } private IEnumerable Read() @@ -129,9 +127,9 @@ public void Release(GameCode code) { lock (_sync) { - if (!_inUse.Contains(code)) return; // generated by the factory - _inUse.Remove(code); - _codes.Add(code); + if (_inUse.Remove(code)) { + _codes.Add(code); + } } } } diff --git a/Handlers/GameEventListener.cs b/Handlers/GameEventListener.cs index 3ce7bea..4986e20 100644 --- a/Handlers/GameEventListener.cs +++ b/Handlers/GameEventListener.cs @@ -1,22 +1,49 @@ +using System.Collections.Generic; using Impostor.Api.Events; +using Impostor.Api.Games; +using Microsoft.Extensions.Logging; namespace Boot.Codes.Handlers { public class GameEventListener : IEventListener { private readonly IGameCodeManager _gameCodeManager; + private readonly ILogger _logger; + private readonly Dictionary _assignmentMap = new(); - public GameEventListener(IGameCodeManager gameCodeManager) + public GameEventListener(IGameCodeManager gameCodeManager, ILogger logger) { - this._gameCodeManager = gameCodeManager; + _gameCodeManager = gameCodeManager; + _logger = logger; } // NOTE: if you want to override the results of Boot.Codes, register an event at a lower priority - [EventListener(EventPriority.Highest)] - public void OnGameCreated(IGameCreationEvent e) => e.GameCode = _gameCodeManager.Get(); + public void OnGameCreation(IGameCreationEvent e) + { + var code = _gameCodeManager.Get(); + e.GameCode = code; + if (e.Client != null) + { + _assignmentMap[e.Client.Id] = code; + } + } - [EventListener(EventPriority.Highest)] + [EventListener] + public void OnGameCreated(IGameCreatedEvent e) + { + if (e.Host != null) + { + var hostId = e.Host.Id; + if (_assignmentMap.Remove(hostId, out var expectedCode) && expectedCode != e.Game.Code) + { + _logger.LogInformation("Boot.Codes provided code was overridden in game {Code}", e.Game.Code); + _gameCodeManager.Release(expectedCode); + } + } + } + + [EventListener] public void OnGameDestroyed(IGameDestroyedEvent e) => _gameCodeManager.Release(e.Game.Code); } }