diff --git a/Pal.Client/Certificate.pfx b/Pal.Client/Certificate.pfx new file mode 100644 index 0000000..8fbc22d Binary files /dev/null and b/Pal.Client/Certificate.pfx differ diff --git a/Pal.Client/Commands/ISubCommand.cs b/Pal.Client/Commands/ISubCommand.cs new file mode 100644 index 0000000..c70cbed --- /dev/null +++ b/Pal.Client/Commands/ISubCommand.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace Pal.Client.Commands +{ + public interface ISubCommand + { + IReadOnlyDictionary> GetHandlers(); + } +} diff --git a/Pal.Client/Commands/PalConfigCommand.cs b/Pal.Client/Commands/PalConfigCommand.cs index 296392f..74218e1 100644 --- a/Pal.Client/Commands/PalConfigCommand.cs +++ b/Pal.Client/Commands/PalConfigCommand.cs @@ -1,10 +1,11 @@ -using Dalamud.Interface.Windowing; +using System; +using System.Collections.Generic; using Pal.Client.Configuration; using Pal.Client.Windows; namespace Pal.Client.Commands { - internal class PalConfigCommand + internal class PalConfigCommand : ISubCommand { private readonly IPalacePalConfiguration _configuration; private readonly AgreementWindow _agreementWindow; @@ -20,7 +21,15 @@ namespace Pal.Client.Commands _configWindow = configWindow; } - public void Execute() + + public IReadOnlyDictionary> GetHandlers() + => new Dictionary> + { + { "config", _ => Execute() }, + { "", _ => Execute() } + }; + + private void Execute() { if (_configuration.FirstUse) _agreementWindow.IsOpen = true; diff --git a/Pal.Client/Commands/PalNearCommand.cs b/Pal.Client/Commands/PalNearCommand.cs index 53e9b8a..4649bb5 100644 --- a/Pal.Client/Commands/PalNearCommand.cs +++ b/Pal.Client/Commands/PalNearCommand.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using Dalamud.Game.ClientState; using Pal.Client.DependencyInjection; @@ -8,7 +9,7 @@ using Pal.Client.Rendering; namespace Pal.Client.Commands { - internal sealed class PalNearCommand + internal sealed class PalNearCommand : ISubCommand { private readonly Chat _chat; private readonly ClientState _clientState; @@ -24,23 +25,14 @@ namespace Pal.Client.Commands _floorService = floorService; } - public void Execute(string arguments) - { - switch (arguments) + + public IReadOnlyDictionary> GetHandlers() + => new Dictionary> { - default: - DebugNearest(_ => true); - break; - - case "tnear": - DebugNearest(m => m.Type == MemoryLocation.EType.Trap); - break; - - case "hnear": - DebugNearest(m => m.Type == MemoryLocation.EType.Hoard); - break; - } - } + { "near", _ => DebugNearest(_ => true) }, + { "tnear", _ => DebugNearest(m => m.Type == MemoryLocation.EType.Trap) }, + { "hnear", _ => DebugNearest(m => m.Type == MemoryLocation.EType.Hoard) }, + }; private void DebugNearest(Predicate predicate) { @@ -54,7 +46,7 @@ namespace Pal.Client.Commands var playerPosition = _clientState.LocalPlayer?.Position; if (playerPosition == null) return; - _chat.Message($"{playerPosition}"); + _chat.Message($"Your position: {playerPosition}"); var nearbyMarkers = state.Locations .Where(m => predicate(m)) diff --git a/Pal.Client/Commands/PalStatsCommand.cs b/Pal.Client/Commands/PalStatsCommand.cs index 917efcc..366f97f 100644 --- a/Pal.Client/Commands/PalStatsCommand.cs +++ b/Pal.Client/Commands/PalStatsCommand.cs @@ -1,9 +1,10 @@ using System; +using System.Collections.Generic; using Pal.Client.DependencyInjection; namespace Pal.Client.Commands { - internal sealed class PalStatsCommand + internal sealed class PalStatsCommand : ISubCommand { private readonly StatisticsService _statisticsService; @@ -12,7 +13,13 @@ namespace Pal.Client.Commands _statisticsService = statisticsService; } - public void Execute() + public IReadOnlyDictionary> GetHandlers() + => new Dictionary> + { + { "stats", _ => Execute() }, + }; + + private void Execute() => _statisticsService.ShowGlobalStatistics(); } } diff --git a/Pal.Client/Commands/PalTestConnectionCommand.cs b/Pal.Client/Commands/PalTestConnectionCommand.cs index 174330c..0ad6e41 100644 --- a/Pal.Client/Commands/PalTestConnectionCommand.cs +++ b/Pal.Client/Commands/PalTestConnectionCommand.cs @@ -1,9 +1,11 @@ -using ECommons.Schedulers; +using System; +using System.Collections.Generic; +using ECommons.Schedulers; using Pal.Client.Windows; namespace Pal.Client.Commands { - internal sealed class PalTestConnectionCommand + internal sealed class PalTestConnectionCommand : ISubCommand { private readonly ConfigWindow _configWindow; @@ -12,7 +14,14 @@ namespace Pal.Client.Commands _configWindow = configWindow; } - public void Execute() + public IReadOnlyDictionary> GetHandlers() + => new Dictionary> + { + { "test-connection", _ => Execute() }, + { "tc", _ => Execute() }, + }; + + private void Execute() { var _ = new TickScheduler(() => _configWindow.TestConnection()); } diff --git a/Pal.Client/DependencyContextInitializer.cs b/Pal.Client/DependencyContextInitializer.cs index 8308f3f..58b6f52 100644 --- a/Pal.Client/DependencyContextInitializer.cs +++ b/Pal.Client/DependencyContextInitializer.cs @@ -69,10 +69,7 @@ namespace Pal.Client _serviceProvider.GetRequiredService(); // eager load any commands to find errors now, not when running them - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); + _serviceProvider.GetRequiredService>(); cancellationToken.ThrowIfCancellationRequested(); diff --git a/Pal.Client/DependencyInjectionContext.cs b/Pal.Client/DependencyInjectionContext.cs index 918dbe2..9632c3b 100644 --- a/Pal.Client/DependencyInjectionContext.cs +++ b/Pal.Client/DependencyInjectionContext.cs @@ -113,10 +113,10 @@ namespace Pal.Client _serviceCollection.AddTransient(); // commands - _serviceCollection.AddScoped(); - _serviceCollection.AddScoped(); - _serviceCollection.AddScoped(); - _serviceCollection.AddScoped(); + _serviceCollection.AddScoped(); + _serviceCollection.AddScoped(); + _serviceCollection.AddScoped(); + _serviceCollection.AddScoped(); // territory & marker related services _serviceCollection.AddScoped(); diff --git a/Pal.Client/Plugin.cs b/Pal.Client/Plugin.cs index e1409dd..7a064b7 100644 --- a/Pal.Client/Plugin.cs +++ b/Pal.Client/Plugin.cs @@ -2,6 +2,7 @@ using Dalamud.Plugin; using Pal.Client.Rendering; using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; @@ -165,45 +166,36 @@ namespace Pal.Client return; } - var sp = rootScope.ServiceProvider; - - switch (arguments) - { - case "": - case "config": - sp.GetRequiredService().Execute(); - break; - - case "stats": - sp.GetRequiredService().Execute(); - break; - - case "tc": - case "test-connection": - sp.GetRequiredService().Execute(); - break; - - case "near": - case "tnear": - case "hnear": - sp.GetRequiredService().Execute(arguments); - break; - - default: - chat.Error(string.Format(Localization.Command_pal_UnknownSubcommand, arguments, + Action commandHandler = rootScope.ServiceProvider + .GetRequiredService>() + .SelectMany(cmd => cmd.GetHandlers()) + .Where(cmd => cmd.Key == arguments.ToLowerInvariant()) + .Select(cmd => cmd.Value) + .SingleOrDefault(missingCommand => + { + chat.Error(string.Format(Localization.Command_pal_UnknownSubcommand, missingCommand, command)); - break; - } + }); + commandHandler.Invoke(arguments); } catch (Exception e) { + _logger.LogError(e, "Could not execute command '{Command}' with arguments '{Arguments}'", command, + arguments); chat.Error(e.ToString()); } }); } private void OpenConfigUi() - => _rootScope!.ServiceProvider.GetRequiredService().Execute(); + { + _rootScope!.ServiceProvider.GetRequiredService>() + .SelectMany(cmd => cmd.GetHandlers()) + .Where(cmd => cmd.Key == "config") + .Select(cmd => cmd.Value) + .Single() + .Invoke("config"); + } private void LanguageChanged(string languageCode) { diff --git a/Pal.Client/Secrets.cs b/Pal.Client/Secrets.cs new file mode 100644 index 0000000..4f294d8 Binary files /dev/null and b/Pal.Client/Secrets.cs differ diff --git a/codesigning.pfx b/codesigning.pfx new file mode 100644 index 0000000..c46585a Binary files /dev/null and b/codesigning.pfx differ