From 3e5282df879858e1f79cd475f4d32eff87d1d182 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Sat, 2 Feb 2019 18:54:30 -0600 Subject: [PATCH] Finish preliminary parser for TeknoMW3 --- .../EventParsers/DynamicEventParser.cs | 1 - .../DynamicEventParserConfiguration.cs | 1 - Application/EventParsers/IW4EventParser.cs | 2 + Application/IW4MServer.cs | 44 +++++++++++-------- Application/RconParsers/DynamicRConParser.cs | 1 - Application/RconParsers/IW4RConParser.cs | 8 ++-- Application/RconParsers/T6MRConParser.cs | 1 + .../Configuration/ApplicationConfiguration.cs | 1 + SharedLibraryCore/Helpers/ParserRegex.cs | 16 +++++++ SharedLibraryCore/Interfaces/IEventParser.cs | 7 +-- SharedLibraryCore/Interfaces/IRConParser.cs | 1 + SharedLibraryCore/Objects/EFClient.cs | 4 +- 12 files changed, 56 insertions(+), 31 deletions(-) diff --git a/Application/EventParsers/DynamicEventParser.cs b/Application/EventParsers/DynamicEventParser.cs index c8680b1d6..116b01532 100644 --- a/Application/EventParsers/DynamicEventParser.cs +++ b/Application/EventParsers/DynamicEventParser.cs @@ -7,6 +7,5 @@ namespace IW4MAdmin.Application.EventParsers { sealed internal class DynamicEventParser : IW4EventParser { - public string Version { get; set; } } } diff --git a/Application/EventParsers/DynamicEventParserConfiguration.cs b/Application/EventParsers/DynamicEventParserConfiguration.cs index 240f67b56..d4f5b61ef 100644 --- a/Application/EventParsers/DynamicEventParserConfiguration.cs +++ b/Application/EventParsers/DynamicEventParserConfiguration.cs @@ -5,7 +5,6 @@ namespace IW4MAdmin.Application.EventParsers class DynamicEventParserConfiguration : IEventParserConfiguration { public string GameDirectory { get; set; } - public ParserRegex Say { get; set; } = new ParserRegex(); public ParserRegex Join { get; set; } = new ParserRegex(); public ParserRegex Quit { get; set; } = new ParserRegex(); diff --git a/Application/EventParsers/IW4EventParser.cs b/Application/EventParsers/IW4EventParser.cs index 795e846a9..685334b74 100644 --- a/Application/EventParsers/IW4EventParser.cs +++ b/Application/EventParsers/IW4EventParser.cs @@ -68,6 +68,8 @@ namespace IW4MAdmin.Application.EventParsers public IEventParserConfiguration Configuration { get; set; } + public string Version { get; set; } = "IW4x (v0.6.0)"; + public virtual GameEvent GetEvent(Server server, string logLine) { logLine = Regex.Replace(logLine, @"([0-9]+:[0-9]+ |^[0-9]+ )", "").Trim(); diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index 4496a162d..82ac5a359 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -665,13 +665,19 @@ namespace IW4MAdmin public async Task Initialize() { - //RemoteConnection.SetConfiguration(Manager.AdditionalRConParsers.First().Configuration); + var rconParser = Manager.AdditionalRConParsers + .FirstOrDefault(_parser => _parser.Version == Manager.GetApplicationSettings().Configuration().CustomParserVersion); - RconParser = ServerConfig.UseT6MParser ? - (IRConParser)new T6MRConParser() : - new IW4RConParser(); + var eventParser = Manager.AdditionalEventParsers + .FirstOrDefault(_parser => _parser.Version == Manager.GetApplicationSettings().Configuration().CustomParserVersion); - RemoteConnection.SetConfiguration(RconParser.Configuration); + rconParser = rconParser ?? new IW4RConParser(); + eventParser = eventParser ?? new IW4EventParser(); + + RemoteConnection.SetConfiguration(rconParser.Configuration); + + RconParser = rconParser; + EventParser = eventParser; var version = await this.GetDvarAsync("version"); Version = version.Value; @@ -693,18 +699,18 @@ namespace IW4MAdmin EventParser = new T6MEventParser(); } - else - { - EventParser = new IW3EventParser(); // this uses the 'main' folder for log paths - } + //else + //{ + // EventParser = new IW3EventParser(); // this uses the 'main' folder for log paths + //} - if (GameName == Game.UKN) - { - Logger.WriteWarning($"Game name not recognized: {version}"); + //if (GameName == Game.UKN) + //{ + // Logger.WriteWarning($"Game name not recognized: {version}"); - EventParser = Manager.AdditionalEventParsers.FirstOrDefault(_parser => (_parser as DynamicEventParser).Version == version.Value) ?? EventParser; - RconParser = Manager.AdditionalRConParsers.FirstOrDefault(_parser => (_parser as DynamicRConParser).Version == version.Value) ?? RconParser; - } + // EventParser = Manager.AdditionalEventParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? EventParser; + // RconParser = Manager.AdditionalRConParsers.FirstOrDefault(_parser => (_parser as DynamicRConParser).Version == version.Value) ?? RconParser; + //} var infoResponse = RconParser.Configuration.CommandPrefixes.RConGetInfo != null ? await this.GetInfoAsync() : null; // this is normally slow, but I'm only doing it because different games have different prefixes @@ -750,7 +756,7 @@ namespace IW4MAdmin this.MaxClients = maxplayers; this.FSGame = game; this.Gametype = gametype; - this.IP = ip.Value == "localhost" ? ServerConfig.IPAddress : ip.Value; + this.IP = ip.Value == "localhost" ? ServerConfig.IPAddress : ip.Value ?? ServerConfig.IPAddress; if (logsync.Value == 0 || logfile.Value == string.Empty) { @@ -767,9 +773,9 @@ namespace IW4MAdmin string mainPath = EventParser.Configuration.GameDirectory; string logPath = string.Empty; - LogPath = game == string.Empty ? - $"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" : - $"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{game.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{logfile.Value}"; + LogPath = string.IsNullOrEmpty(game) ? + $"{basepath?.Value?.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile?.Value}" : + $"{basepath?.Value?.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{game?.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{logfile?.Value}"; bool remoteLog = false; if (GameName == Game.IW5 || ServerConfig.ManualLogPath?.Length > 0) diff --git a/Application/RconParsers/DynamicRConParser.cs b/Application/RconParsers/DynamicRConParser.cs index 4fe14f672..ec46f4cd2 100644 --- a/Application/RconParsers/DynamicRConParser.cs +++ b/Application/RconParsers/DynamicRConParser.cs @@ -7,6 +7,5 @@ namespace IW4MAdmin.Application.RconParsers { sealed internal class DynamicRConParser : IW4RConParser { - public string Version { get; set; } } } diff --git a/Application/RconParsers/IW4RConParser.cs b/Application/RconParsers/IW4RConParser.cs index 17fe16290..8ee8c91b5 100644 --- a/Application/RconParsers/IW4RConParser.cs +++ b/Application/RconParsers/IW4RConParser.cs @@ -50,6 +50,8 @@ namespace IW4MAdmin.Application.RconParsers public IRConParserConfiguration Configuration { get; set; } + public string Version { get; set; } = "IW4x (v0.6.0)"; + public async Task ExecuteCommandAsync(Connection connection, string command) { var response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, command); @@ -61,7 +63,7 @@ namespace IW4MAdmin.Application.RconParsers string[] lineSplit = await connection.SendQueryAsync(StaticHelpers.QueryType.DVAR, dvarName); string response = string.Join('\n', lineSplit.Skip(1)); - if (lineSplit[0] != Configuration.CommandPrefixes.RConResponse) + if (!lineSplit[0].Contains(Configuration.CommandPrefixes.RConResponse)) { throw new DvarException($"Could not retrieve DVAR \"{dvarName}\""); } @@ -113,9 +115,9 @@ namespace IW4MAdmin.Application.RconParsers } int validMatches = 0; - foreach (String S in Status) + foreach (string S in Status) { - String responseLine = S.Trim(); + string responseLine = S.Trim(); var regex = Regex.Match(responseLine, Configuration.Status.Pattern, RegexOptions.IgnoreCase); diff --git a/Application/RconParsers/T6MRConParser.cs b/Application/RconParsers/T6MRConParser.cs index d32a5ab7a..7d60ff642 100644 --- a/Application/RconParsers/T6MRConParser.cs +++ b/Application/RconParsers/T6MRConParser.cs @@ -14,6 +14,7 @@ namespace IW4MAdmin.Application.RconParsers public class T6MRConParser : IRConParser { public IRConParserConfiguration Configuration { get; set; } + public string Version { get; set; } = ""; public T6MRConParser() { diff --git a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs index f1a89befc..e58b58254 100644 --- a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs +++ b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs @@ -28,6 +28,7 @@ namespace SharedLibraryCore.Configuration public string Id { get; set; } public List Servers { get; set; } public int AutoMessagePeriod { get; set; } + public string CustomParserVersion { get; set; } public List AutoMessages { get; set; } public List GlobalRules { get; set; } public List Maps { get; set; } diff --git a/SharedLibraryCore/Helpers/ParserRegex.cs b/SharedLibraryCore/Helpers/ParserRegex.cs index 390e1ef62..d1eca175c 100644 --- a/SharedLibraryCore/Helpers/ParserRegex.cs +++ b/SharedLibraryCore/Helpers/ParserRegex.cs @@ -38,6 +38,22 @@ namespace SharedLibraryCore.Interfaces public string Pattern { get; set; } public Dictionary GroupMapping { get; private set; } + public void AddMapping(object mapKey, object mapValue) + { + if (int.TryParse(mapKey.ToString(), out int key) && int.TryParse(mapValue.ToString(), out int value)) + { + if (GroupMapping.ContainsKey((GroupType)key)) + { + GroupMapping[(GroupType)key] = value; + } + + else + { + GroupMapping.Add((GroupType)key, value); + } + } + } + public ParserRegex() { GroupMapping = new Dictionary(); diff --git a/SharedLibraryCore/Interfaces/IEventParser.cs b/SharedLibraryCore/Interfaces/IEventParser.cs index 3caaff6cc..d21a489d6 100644 --- a/SharedLibraryCore/Interfaces/IEventParser.cs +++ b/SharedLibraryCore/Interfaces/IEventParser.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace SharedLibraryCore.Interfaces +namespace SharedLibraryCore.Interfaces { public interface IEventParser { @@ -19,5 +15,6 @@ namespace SharedLibraryCore.Interfaces /// /// Game directory prefix IEventParserConfiguration Configuration { get; set; } + string Version { get; set; } } } diff --git a/SharedLibraryCore/Interfaces/IRConParser.cs b/SharedLibraryCore/Interfaces/IRConParser.cs index 4346ed89d..ae513ca3b 100644 --- a/SharedLibraryCore/Interfaces/IRConParser.cs +++ b/SharedLibraryCore/Interfaces/IRConParser.cs @@ -14,5 +14,6 @@ namespace SharedLibraryCore.Interfaces Task ExecuteCommandAsync(Connection connection, string command); Task> GetStatusAsync(Connection connection); IRConParserConfiguration Configuration { get; set; } + string Version { get; set; } } } diff --git a/SharedLibraryCore/Objects/EFClient.cs b/SharedLibraryCore/Objects/EFClient.cs index 4fe76a835..04142cbf1 100644 --- a/SharedLibraryCore/Objects/EFClient.cs +++ b/SharedLibraryCore/Objects/EFClient.cs @@ -435,7 +435,9 @@ namespace SharedLibraryCore.Database.Models // reserved slots stuff // todo: bots don't seem to honor party_maxplayers/sv_maxclients if (CurrentServer.MaxClients - (CurrentServer.GetClientsAsList().Count(_client => !_client.IsPrivileged())) < CurrentServer.ServerConfig.ReservedSlotNumber && - !this.IsPrivileged()) + !this.IsPrivileged() && + CurrentServer.GetClientsAsList().Count <= CurrentServer.MaxClients && + CurrentServer.MaxClients != 0) { CurrentServer.Logger.WriteDebug($"Kicking {this} their spot is reserved"); Kick(loc["SERVER_KICK_SLOT_IS_RESERVED"], Utilities.IW4MAdminClient(CurrentServer));