From 2bbafbd8f0ad0e4031ab0acbb6b1c345bae3f54a Mon Sep 17 00:00:00 2001 From: RaidMax Date: Sat, 17 Oct 2020 10:47:56 -0500 Subject: [PATCH] fix issue with delay on map command --- SharedLibraryCore/Commands/NativeCommands.cs | 30 ++++---- .../Configuration/ApplicationConfiguration.cs | 2 + SharedLibraryCore/Database/DatabaseContext.cs | 13 +++- SharedLibraryCore/Server.cs | 2 +- .../ApplicationTests/ApplicationTests.csproj | 1 + Tests/ApplicationTests/CommandTests.cs | 71 +++++++++++++------ .../DependencyInjectionExtensions.cs | 6 +- 7 files changed, 84 insertions(+), 41 deletions(-) diff --git a/SharedLibraryCore/Commands/NativeCommands.cs b/SharedLibraryCore/Commands/NativeCommands.cs index df91d0892..e3f4e97b1 100644 --- a/SharedLibraryCore/Commands/NativeCommands.cs +++ b/SharedLibraryCore/Commands/NativeCommands.cs @@ -632,11 +632,11 @@ namespace SharedLibraryCore.Commands public override async Task ExecuteAsync(GameEvent E) { - var _ = !E.Origin.Masked ? + _ = !E.Origin.Masked ? E.Owner.Broadcast($"{_translationLookup["COMMANDS_MAPROTATE"]} [^5{E.Origin.Name}^7]", E.Origin) : E.Owner.Broadcast(_translationLookup["COMMANDS_MAPROTATE"], E.Origin); - await Task.Delay(5000); + await Task.Delay(E.Owner.Manager.GetApplicationSettings().Configuration().MapChangeDelaySeconds * 1000); await E.Owner.ExecuteCommandAsync("map_rotate"); } } @@ -864,21 +864,17 @@ namespace SharedLibraryCore.Commands public override async Task ExecuteAsync(GameEvent E) { - string newMap = E.Data.Trim().ToLower(); - foreach (Map m in E.Owner.Maps) - { - if (m.Name.ToLower() == newMap || m.Alias.ToLower() == newMap) - { - E.Owner.Broadcast(_translationLookup["COMMANDS_MAP_SUCCESS"].FormatExt(m.Alias)); - await Task.Delay((int)(Utilities.DefaultCommandTimeout.TotalMilliseconds / 2.0)); - await E.Owner.LoadMap(m.Name); - return; - } - } + string newMap = E.Data.Trim(); + int delay = E.Owner.Manager.GetApplicationSettings().Configuration().MapChangeDelaySeconds * 1000; - // todo: this can be moved into a single statement - E.Owner.Broadcast(_translationLookup["COMMANDS_MAP_UKN"].FormatExt(newMap)); - await Task.Delay(5000); + var foundMap = E.Owner.Maps.FirstOrDefault(_map => _map.Name.Equals(newMap, StringComparison.InvariantCultureIgnoreCase) || + _map.Alias.Equals(newMap, StringComparison.InvariantCultureIgnoreCase)); + + _ = foundMap == null ? + E.Owner.Broadcast(_translationLookup["COMMANDS_MAP_UKN"].FormatExt(newMap)) : + E.Owner.Broadcast(_translationLookup["COMMANDS_MAP_SUCCESS"].FormatExt(foundMap.Alias)); + + await Task.Delay(delay); await E.Owner.LoadMap(newMap); } } @@ -1565,7 +1561,7 @@ namespace SharedLibraryCore.Commands /// public class SetGravatarCommand : Command { - private readonly IMetaService _metaService; + private readonly IMetaService _metaService; public SetGravatarCommand(CommandConfiguration config, ITranslationLookup translationLookup, IMetaService metaService) : base(config, translationLookup) { diff --git a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs index debf7c1f2..c2cf6491e 100644 --- a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs +++ b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs @@ -91,6 +91,8 @@ namespace SharedLibraryCore.Configuration public string[] GlobalRules { get; set; } = new string[0]; [LocalizedDisplayName("WEBFRONT_CONFIGURATION_DISALLOWED_NAMES")] public string[] DisallowedClientNames { get; set; } = new string[0]; + [LocalizedDisplayName("WEBFRONT_CONFIGURATION_MAP_CHANGE_DELAY")] + public int MapChangeDelaySeconds { get; set; } = 5; [UIHint("ServerConfiguration")] public ServerConfiguration[] Servers { get; set; } diff --git a/SharedLibraryCore/Database/DatabaseContext.cs b/SharedLibraryCore/Database/DatabaseContext.cs index 948f5eb14..f6b11ab0b 100644 --- a/SharedLibraryCore/Database/DatabaseContext.cs +++ b/SharedLibraryCore/Database/DatabaseContext.cs @@ -205,7 +205,18 @@ namespace SharedLibraryCore.Database pluginDir = Path.Join(Utilities.OperatingDirectory, "..", "..", "..", "..", "BUILD", "Plugins"); } - IEnumerable directoryFiles = Directory.GetFiles(pluginDir).Where(f => f.EndsWith(".dll")); + IEnumerable directoryFiles = Enumerable.Empty(); + + try + { + directoryFiles = Directory.GetFiles(pluginDir).Where(f => f.EndsWith(".dll")); + } + + catch (DirectoryNotFoundException) + { + // this is just an ugly thing for unit testing + directoryFiles = Directory.GetFiles(@"X:\IW4MAdmin\Tests\ApplicationTests\bin\Debug\netcoreapp3.1").Where(f => f.EndsWith("dll")); + } foreach (string dllPath in directoryFiles) { diff --git a/SharedLibraryCore/Server.cs b/SharedLibraryCore/Server.cs index 5b5a8f9d7..58332bb98 100644 --- a/SharedLibraryCore/Server.cs +++ b/SharedLibraryCore/Server.cs @@ -122,7 +122,7 @@ namespace SharedLibraryCore /// Message to be sent to all players public GameEvent Broadcast(string message, EFClient sender = null) { - string formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Say, $"{(CustomSayEnabled && GameName == Game.IW4 ? $"{CustomSayName}: " : "")}{message.FixIW4ForwardSlash()}"); + string formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Say ?? "", $"{(CustomSayEnabled && GameName == Game.IW4 ? $"{CustomSayName}: " : "")}{message.FixIW4ForwardSlash()}"); #if DEBUG == true Logger.WriteVerbose(message.StripColors()); #endif diff --git a/Tests/ApplicationTests/ApplicationTests.csproj b/Tests/ApplicationTests/ApplicationTests.csproj index d41f5f2af..1c28ad4bf 100644 --- a/Tests/ApplicationTests/ApplicationTests.csproj +++ b/Tests/ApplicationTests/ApplicationTests.csproj @@ -7,6 +7,7 @@ + diff --git a/Tests/ApplicationTests/CommandTests.cs b/Tests/ApplicationTests/CommandTests.cs index 0576f924b..2bcc6c48c 100644 --- a/Tests/ApplicationTests/CommandTests.cs +++ b/Tests/ApplicationTests/CommandTests.cs @@ -14,6 +14,8 @@ using SharedLibraryCore; using ApplicationTests.Mocks; using SharedLibraryCore.Services; using static SharedLibraryCore.Database.Models.EFClient; +using FluentAssertions; +using FluentAssertions.Extensions; namespace ApplicationTests { @@ -33,11 +35,14 @@ namespace ApplicationTests public void Setup() { logger = A.Fake(); - cmdConfig = new CommandConfiguration(); serviceProvider = new ServiceCollection() .BuildBase(new EventHandlerMock(true)) .AddSingleton(A.Fake()) + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() .BuildServiceProvider() .SetupTestHooks(); @@ -46,6 +51,8 @@ namespace ApplicationTests transLookup = serviceProvider.GetRequiredService(); clientService = serviceProvider.GetRequiredService(); appConfig = serviceProvider.GetRequiredService(); + appConfig.MapChangeDelaySeconds = 1; + cmdConfig = serviceProvider.GetRequiredService(); A.CallTo(() => manager.GetClientService()) .Returns(clientService); @@ -69,7 +76,7 @@ namespace ApplicationTests [Test] public async Task Test_RunAsFailsOnSelf() { - var cmd = new RunAsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var target = ClientGenerators.CreateBasicClient(server); @@ -88,7 +95,7 @@ namespace ApplicationTests [Test] public async Task Test_RunAsFailsOnHigherPrivilege() { - var cmd = new RunAsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var target = ClientGenerators.CreateBasicClient(server); target.Level = EFClient.Permission.Administrator; @@ -111,7 +118,7 @@ namespace ApplicationTests [Test] public async Task Test_RunAsFailsOnSamePrivilege() { - var cmd = new RunAsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var target = ClientGenerators.CreateBasicClient(server); target.Level = EFClient.Permission.Administrator; @@ -134,7 +141,7 @@ namespace ApplicationTests [Test] public async Task Test_RunAsFailsOnDisallowedCommand() { - var cmd = new RunAsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var target = ClientGenerators.CreateBasicClient(server); target.Level = EFClient.Permission.Moderator; @@ -160,7 +167,7 @@ namespace ApplicationTests [Test] public async Task Test_RunAsQueuesEventAndResponse() { - var cmd = new RunAsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var target = ClientGenerators.CreateBasicClient(server); target.Level = EFClient.Permission.Moderator; @@ -187,7 +194,7 @@ namespace ApplicationTests [Test] public async Task Test_SetLevelFailOnSelf() { - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var target = ClientGenerators.CreateBasicClient(server); target.Level = Permission.Owner; @@ -211,7 +218,7 @@ namespace ApplicationTests public async Task Test_SetLevelFailWithSourcePrivilegeTooLow() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Moderator; var target = ClientGenerators.CreateBasicClient(server); @@ -239,7 +246,7 @@ namespace ApplicationTests public async Task Test_SetLevelFailWithExistingOwner_AndOnlyOneOwnerAllowed() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); var target = ClientGenerators.CreateBasicClient(server); target.Level = Permission.User; @@ -266,7 +273,7 @@ namespace ApplicationTests public async Task Test_SetLevelFailWithStepPrivilegesDisabled_AndNonOwner() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.SeniorAdmin; var target = ClientGenerators.CreateBasicClient(server); @@ -294,7 +301,7 @@ namespace ApplicationTests public async Task Test_SetLevelFailWithStepPrivilegesEnabled_ButNewPermissionTooHigh() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Moderator; var target = ClientGenerators.CreateBasicClient(server); @@ -320,7 +327,7 @@ namespace ApplicationTests public async Task Test_SetLevelFailInvalidGroup() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Owner; var target = ClientGenerators.CreateBasicClient(server); @@ -345,7 +352,7 @@ namespace ApplicationTests public async Task Test_SetLevelSucceedWithNoExistingOwner_AndOnlyOneOwnerAllowed() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Owner; var target = ClientGenerators.CreateBasicClient(server); @@ -373,7 +380,7 @@ namespace ApplicationTests public async Task Test_SetLevelOwnerSucceedWithMultiOwnerAllowed() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Owner; var target = ClientGenerators.CreateBasicClient(server); @@ -402,7 +409,7 @@ namespace ApplicationTests public async Task Test_SetLevelOwnerSucceedWithMultiOwnerAllowed_AndSteppedPrivileges() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Owner; var target = ClientGenerators.CreateBasicClient(server); @@ -432,7 +439,7 @@ namespace ApplicationTests public async Task Test_SetLevelSucceedWithSteppedPrivileges() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Moderator; var target = ClientGenerators.CreateBasicClient(server); @@ -461,7 +468,7 @@ namespace ApplicationTests public async Task Test_SetLevelSucceed() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Owner; var target = ClientGenerators.CreateBasicClient(server); @@ -490,7 +497,7 @@ namespace ApplicationTests public async Task Test_SetLevelSucceed_AndFindsIngameClient() { var server = serviceProvider.GetRequiredService(); - var cmd = new SetLevelCommand(cmdConfig, transLookup, logger); + var cmd = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateBasicClient(server); origin.Level = Permission.Owner; var databaseTarget = ClientGenerators.CreateDatabaseClient(); @@ -542,14 +549,14 @@ namespace ApplicationTests [Test] public async Task Test_PrivateMessageAdmins_HappyPath() { - var cmd = new PrivateMessageAdminsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateDatabaseClient(); origin.Level = Permission.Administrator; origin.CurrentServer = server; var gameEvent = EventGenerators.GenerateEvent(GameEvent.EventType.Command, "", server); cmdConfig.Commands.Add(nameof(PrivateMessageAdminsCommand), new CommandProperties { SupportedGames = new[] { server.GameName } }); - + server.Clients[0] = origin; server.Clients[1] = origin; await cmd.ExecuteAsync(gameEvent); @@ -561,7 +568,7 @@ namespace ApplicationTests [Test] public async Task Test_PrivateMessageAdmins_GameNotSupported() { - var cmd = new PrivateMessageAdminsCommand(cmdConfig, transLookup); + var cmd = serviceProvider.GetRequiredService(); var server = serviceProvider.GetRequiredService(); var origin = ClientGenerators.CreateDatabaseClient(); origin.Level = Permission.Administrator; @@ -578,5 +585,27 @@ namespace ApplicationTests Assert.AreEqual(expectedEvents, mockEventHandler.Events.Count(_event => _event.Type == GameEvent.EventType.Tell)); } #endregion + + #region LOADMAP + [Test] + public void Test_LoadMap_WaitsAppropriateTime_BeforeExecutingCommand() + { + var cmd = serviceProvider.GetRequiredService(); + var server = serviceProvider.GetRequiredService(); + var rconParser = serviceProvider.GetRequiredService(); + server.Maps.Add(new Map() + { + Name = "mp_test", + Alias = "test" + }); + var gameEvent = EventGenerators.GenerateEvent(GameEvent.EventType.Command, server.Maps.First().Name, server); + + Func act = () => cmd.ExecuteAsync(gameEvent); + + act.ExecutionTime().Should().BeCloseTo(appConfig.MapChangeDelaySeconds.Seconds(), 500.Milliseconds()); + A.CallTo(() => rconParser.ExecuteCommandAsync(A.Ignored, A.Ignored)) + .MustHaveHappened(); + } + #endregion } } diff --git a/Tests/ApplicationTests/DependencyInjectionExtensions.cs b/Tests/ApplicationTests/DependencyInjectionExtensions.cs index 76dcc2b3e..954c7a4c3 100644 --- a/Tests/ApplicationTests/DependencyInjectionExtensions.cs +++ b/Tests/ApplicationTests/DependencyInjectionExtensions.cs @@ -30,6 +30,10 @@ namespace ApplicationTests var manager = A.Fake(); var logger = A.Fake(); + var transLookup = A.Fake(); + A.CallTo(() => transLookup[A.Ignored]) + .Returns("test"); + A.CallTo(() => manager.GetLogger(A.Ignored)) .Returns(logger); @@ -38,7 +42,7 @@ namespace ApplicationTests .AddSingleton() .AddSingleton(A.Fake()) .AddSingleton(A.Fake()) - .AddSingleton(A.Fake()) + .AddSingleton(transLookup) .AddSingleton(A.Fake()) .AddSingleton(A.Fake()) .AddSingleton()