diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index 1ed682c99..61d7acf50 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -498,7 +498,7 @@ namespace IW4MAdmin Hostname = dict["hostname"]; string mapname = dict["mapname"] ?? CurrentMap.Name; - CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; + UpdateMap(mapname); } } @@ -510,11 +510,7 @@ namespace IW4MAdmin MaxClients = int.Parse(dict["sv_maxclients"]); string mapname = dict["mapname"]; - CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() - { - Alias = mapname, - Name = mapname - }; + UpdateMap(mapname); } } @@ -598,7 +594,8 @@ namespace IW4MAdmin var now = DateTime.Now; #endif var currentClients = GetClientsAsList(); - var polledClients = (await this.GetStatusAsync()).AsEnumerable(); + var statusResponse = (await this.GetStatusAsync()); + var polledClients = statusResponse.Item1.AsEnumerable(); if (Manager.GetApplicationSettings().Configuration().IgnoreBots) { @@ -611,6 +608,8 @@ namespace IW4MAdmin var connectingClients = polledClients.Except(currentClients); var updatedClients = polledClients.Except(connectingClients).Except(disconnectingClients); + UpdateMap(statusResponse.Item2); + return new List[] { connectingClients.ToList(), @@ -619,6 +618,18 @@ namespace IW4MAdmin }; } + private void UpdateMap(string mapname) + { + if (!string.IsNullOrEmpty(mapname)) + { + CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() + { + Alias = mapname, + Name = mapname + }; + } + } + private async Task ShutdownInternal() { foreach (var client in GetClientsAsList()) @@ -887,11 +898,11 @@ namespace IW4MAdmin InitializeMaps(); this.Hostname = hostname; - this.CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; this.MaxClients = maxplayers; this.FSGame = game; this.Gametype = gametype; this.IP = ip.Value == "localhost" ? ServerConfig.IPAddress : ip.Value ?? ServerConfig.IPAddress; + UpdateMap(mapname); if (RconParser.CanGenerateLogPath) { diff --git a/Application/RconParsers/BaseRConParser.cs b/Application/RconParsers/BaseRConParser.cs index 4ca038eca..e7b72801a 100644 --- a/Application/RconParsers/BaseRConParser.cs +++ b/Application/RconParsers/BaseRConParser.cs @@ -52,6 +52,9 @@ namespace IW4MAdmin.Application.RconParsers Configuration.Dvar.AddMapping(ParserRegex.GroupType.RConDvarDefaultValue, 3); Configuration.Dvar.AddMapping(ParserRegex.GroupType.RConDvarLatchedValue, 4); Configuration.Dvar.AddMapping(ParserRegex.GroupType.RConDvarDomain, 5); + + Configuration.MapStatus.Pattern = @"map: (([a-z]|_|\d)+)"; + Configuration.MapStatus.AddMapping(ParserRegex.GroupType.RConStatusMap, 1); } public IRConParserConfiguration Configuration { get; set; } @@ -100,7 +103,7 @@ namespace IW4MAdmin.Application.RconParsers }; } - public virtual async Task> GetStatusAsync(Connection connection) + public virtual async Task<(List, string)> GetStatusAsync(Connection connection) { string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND_STATUS); #if DEBUG @@ -109,7 +112,22 @@ namespace IW4MAdmin.Application.RconParsers Console.WriteLine(line); } #endif - return ClientsFromStatus(response); + return (ClientsFromStatus(response), MapFromStatus(response)); + } + + private string MapFromStatus(string[] response) + { + string map = null; + foreach (var line in response) + { + var regex = Regex.Match(line, Configuration.MapStatus.Pattern); + if (regex.Success) + { + map = regex.Groups[Configuration.MapStatus.GroupMapping[ParserRegex.GroupType.RConStatusMap]].ToString(); + } + } + + return map; } public async Task SetDvarAsync(Connection connection, string dvarName, object dvarValue) @@ -195,4 +213,5 @@ namespace IW4MAdmin.Application.RconParsers return StatusPlayers; } - }} + } +} diff --git a/Application/RconParsers/DynamicRConParserConfiguration.cs b/Application/RconParsers/DynamicRConParserConfiguration.cs index 447b4ded7..012f3386e 100644 --- a/Application/RconParsers/DynamicRConParserConfiguration.cs +++ b/Application/RconParsers/DynamicRConParserConfiguration.cs @@ -12,6 +12,7 @@ namespace IW4MAdmin.Application.RconParsers { public CommandPrefix CommandPrefixes { get; set; } public ParserRegex Status { get; set; } = new ParserRegex(); + public ParserRegex MapStatus { get; set; } = new ParserRegex(); public ParserRegex Dvar { get; set; } = new ParserRegex(); public bool WaitForResponse { get; set; } = true; } diff --git a/SharedLibraryCore/Helpers/ParserRegex.cs b/SharedLibraryCore/Helpers/ParserRegex.cs index 3848be4af..c257d24b5 100644 --- a/SharedLibraryCore/Helpers/ParserRegex.cs +++ b/SharedLibraryCore/Helpers/ParserRegex.cs @@ -37,6 +37,7 @@ namespace SharedLibraryCore.Interfaces RConDvarDefaultValue = 108, RConDvarLatchedValue = 109, RConDvarDomain = 110, + RConStatusMap = 111, AdditionalGroup = 200 } diff --git a/SharedLibraryCore/Interfaces/IRConParser.cs b/SharedLibraryCore/Interfaces/IRConParser.cs index 51dd192ab..e7b2060db 100644 --- a/SharedLibraryCore/Interfaces/IRConParser.cs +++ b/SharedLibraryCore/Interfaces/IRConParser.cs @@ -38,8 +38,8 @@ namespace SharedLibraryCore.Interfaces /// get the list of connected clients from status response /// /// RCon connection to use - /// - Task> GetStatusAsync(Connection connection); + /// list of clients, and current map + Task<(List, string)> GetStatusAsync(Connection connection); /// /// stores the RCon configuration diff --git a/SharedLibraryCore/Interfaces/IRConParserConfiguration.cs b/SharedLibraryCore/Interfaces/IRConParserConfiguration.cs index 774afea40..dd75e377f 100644 --- a/SharedLibraryCore/Interfaces/IRConParserConfiguration.cs +++ b/SharedLibraryCore/Interfaces/IRConParserConfiguration.cs @@ -8,14 +8,22 @@ namespace SharedLibraryCore.Interfaces /// stores the command format for console commands /// CommandPrefix CommandPrefixes { get; set; } + /// /// stores the regex info for parsing get status response /// ParserRegex Status { get; set; } + + /// + /// stores regex info for parsing the map line from rcon status response + /// + ParserRegex MapStatus { get; set; } + /// /// stores the regex info for parsing get DVAR responses /// ParserRegex Dvar { get; set; } + /// /// indicates if the application should wait for response from server /// when executing a command diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index 5d980dab8..e4b9ecaee 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -718,7 +718,7 @@ namespace SharedLibraryCore return await server.RconParser.ExecuteCommandAsync(server.RemoteConnection, commandName); } - public static Task> GetStatusAsync(this Server server) + public static Task<(List, string)> GetStatusAsync(this Server server) { return server.RconParser.GetStatusAsync(server.RemoteConnection); }