From be8041b8686854e9722e08104ae1e0dbd81bcd52 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Mon, 13 Apr 2020 16:16:31 -0500 Subject: [PATCH] refactor and test log path generation to support pluto IW5 better --- Application/IW4MServer.cs | 52 ++++++++++++------- Plugins/ScriptPlugins/ParserPIW5.js | 8 +-- SharedLibraryCore/Utilities.cs | 16 ++++++ Tests/ApplicationTests/IW4MServerTests.cs | 63 +++++++++++++++++++++++ 4 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 Tests/ApplicationTests/IW4MServerTests.cs diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index 50efd66bc..44b1b073d 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -1,7 +1,5 @@ -using IW4MAdmin.Application.EventParsers; -using IW4MAdmin.Application.IO; +using IW4MAdmin.Application.IO; using IW4MAdmin.Application.Misc; -using IW4MAdmin.Application.RconParsers; using SharedLibraryCore; using SharedLibraryCore.Configuration; using SharedLibraryCore.Database.Models; @@ -945,10 +943,6 @@ namespace IW4MAdmin var logsync = await this.GetDvarAsync("g_logsync"); var ip = await this.GetDvarAsync("net_ip"); - WorkingDirectory = Directory.Exists(basegame?.Value ?? "") ? - basegame.Value : - basepath.Value; - try { var website = await this.GetDvarAsync("_website"); @@ -970,6 +964,7 @@ namespace IW4MAdmin InitializeMaps(); + WorkingDirectory = basepath.Value; this.Hostname = hostname; this.MaxClients = maxplayers; this.FSGame = game; @@ -1014,17 +1009,7 @@ namespace IW4MAdmin else { - string mainPath = EventParser.Configuration.GameDirectory; - - LogPath = string.IsNullOrEmpty(game) ? - $"{WorkingDirectory.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile?.Value}" : - $"{WorkingDirectory.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{game?.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{logfile?.Value}"; - - // fix wine drive name mangling - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - LogPath = Regex.Replace($"{Path.DirectorySeparatorChar}{LogPath}", @"[A-Z]:/", ""); - } + LogPath = GenerateLogPath(basegame.Value, basepath.Value, EventParser.Configuration.GameDirectory, game, logfile.Value); if (!File.Exists(LogPath) && ServerConfig.GameLogServerUrl == null) { @@ -1042,6 +1027,37 @@ namespace IW4MAdmin #endif } + public static string GenerateLogPath(string baseGameDirectory, string basePathDirectory, string gameDirectory, string modDirectory, string logFile) + { + string logPath; + string workingDirectory = basePathDirectory; + + // we want to see if base game is provided and it 'looks' like a directory + if (!string.IsNullOrWhiteSpace(baseGameDirectory) && + baseGameDirectory.IndexOfAny(Utilities.DirectorySeparatorChars) != -1) + { + workingDirectory = baseGameDirectory; + } + + if (string.IsNullOrWhiteSpace(modDirectory)) + { + logPath = Path.Combine(workingDirectory, gameDirectory, logFile); + } + + else + { + logPath = Path.Combine(workingDirectory, modDirectory, logFile); + } + + // fix wine drive name mangling + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + logPath = Regex.Replace($"{Path.DirectorySeparatorChar}{logPath}", @"[A-Z]:/", ""); + } + + return logPath.FixDirectoryCharacters(); + } + protected override async Task Warn(String Reason, EFClient Target, EFClient Origin) { // ensure player gets warned if command not performed on them in game diff --git a/Plugins/ScriptPlugins/ParserPIW5.js b/Plugins/ScriptPlugins/ParserPIW5.js index 667a3b483..abd898558 100644 --- a/Plugins/ScriptPlugins/ParserPIW5.js +++ b/Plugins/ScriptPlugins/ParserPIW5.js @@ -25,7 +25,7 @@ var plugin = { rconParser.Configuration.Dvar.AddMapping(106, 2); rconParser.Configuration.Dvar.AddMapping(107, 3); rconParser.Configuration.WaitForResponse = false; - rconParser.Configuration.CanGenerateLogPath = true; + rconParser.Configuration.CanGenerateLogPath = true; rconParser.Configuration.Status.Pattern = '^ *([0-9]+) +([0-9]+) +(?:[0-1]{1}) +([0-9]+) +([A-F0-9]+) +(.+?) +(?:[0-9]+) +(\\d+\\.\\d+\\.\\d+\\.\\d+\\:-?\\d{1,5}|0+\\.0+:-?\\d{1,5}|loopback) +(?:-?[0-9]+) +(?:[0-9]+) *$'; rconParser.Configuration.Status.AddMapping(100, 1); @@ -36,9 +36,11 @@ var plugin = { rconParser.Configuration.Status.AddMapping(105, 6); rconParser.Version = 'IW5 MP 1.9 build 388110 Fri Sep 14 00:04:28 2012 win-x86'; - rconParser.GameName = 3; // T5 + rconParser.GameName = 3; // IW5 eventParser.Version = 'IW5 MP 1.9 build 388110 Fri Sep 14 00:04:28 2012 win-x86'; - eventParser.GameName = 3; // T5 + eventParser.GameName = 3; // IW5 + + eventParser.Configuration.GameDirectory = ''; }, onUnloadAsync: function () { diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index 0bc918d09..f319a13b5 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -32,6 +32,7 @@ namespace SharedLibraryCore public static Encoding EncodingType; public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary()); public static TimeSpan DefaultCommandTimeout = new TimeSpan(0, 0, 25); + public static char[] DirectorySeparatorChars = new[] { '\\', '/' }; public static EFClient IW4MAdminClient(Server server = null) { @@ -873,6 +874,21 @@ namespace SharedLibraryCore public static bool ShouldHideLevel(this Permission perm) => perm == Permission.Flagged; + /// + /// replaces any directory separator chars with the platform specific character + /// + /// original file path + /// + public static string FixDirectoryCharacters(this string path) + { + foreach (char separator in DirectorySeparatorChars) + { + path = path.Replace(separator, Path.DirectorySeparatorChar); + } + + return path; + } + #if DEBUG == true public static string ToSql(this IQueryable query) where TEntity : class { diff --git a/Tests/ApplicationTests/IW4MServerTests.cs b/Tests/ApplicationTests/IW4MServerTests.cs new file mode 100644 index 000000000..2df1ed945 --- /dev/null +++ b/Tests/ApplicationTests/IW4MServerTests.cs @@ -0,0 +1,63 @@ +using IW4MAdmin; +using NUnit.Framework; + +namespace ApplicationTests +{ + [TestFixture] + public class IW4MServerTests + { + [Test] + public void Test_GenerateLogPath_Basic() + { + string expected = "C:\\Game\\main\\log.log"; + string generated = IW4MServer.GenerateLogPath("", "C:\\Game", "main", null, "log.log"); + + Assert.AreEqual(expected, generated); + } + + [Test] + public void Test_GenerateLogPath_WithMod() + { + string expected = "C:\\Game\\mods\\mod\\log.log"; + string generated = IW4MServer.GenerateLogPath("", "C:\\Game", "main", "mods\\mod", "log.log"); + + Assert.AreEqual(expected, generated); + } + + [Test] + public void Test_GenerateLogPath_WithBasePath() + { + string expected = "C:\\GameAlt\\main\\log.log"; + string generated = IW4MServer.GenerateLogPath("C:\\GameAlt", "C:\\Game", "main", null, "log.log"); + + Assert.AreEqual(expected, generated); + } + + [Test] + public void Test_GenerateLogPath_WithBasePathAndMod() + { + string expected = "C:\\GameAlt\\mods\\mod\\log.log"; + string generated = IW4MServer.GenerateLogPath("C:\\GameAlt", "C:\\Game", "main", "mods\\mod", "log.log"); + + Assert.AreEqual(expected, generated); + } + + [Test] + public void Test_GenerateLogPath_InvalidBasePath() + { + string expected = "C:\\Game\\main\\log.log"; + string generated = IW4MServer.GenerateLogPath("game", "C:\\Game", "main", null, "log.log"); + + Assert.AreEqual(expected, generated); + } + + [Test] + public void Test_GenerateLogPath_BadSeparators() + { + string expected = "C:\\Game\\main\\folder\\log.log"; + string generated = IW4MServer.GenerateLogPath("", "C:/Game", "main/folder", null, "log.log"); + + Assert.AreEqual(expected, generated); + } + } +}