adjustments for T6 and tekno (implement mapped dvars and default values)

This commit is contained in:
RaidMax 2020-06-16 17:16:12 -05:00
parent ba77e0149c
commit bb4e51d9c8
9 changed files with 109 additions and 51 deletions

View File

@ -42,7 +42,7 @@ namespace IW4MAdmin.Application.EventParsers
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginName, 4);
Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
Configuration.Damage.AddMapping(ParserRegex.GroupType.EventType, 1);
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
@ -57,7 +57,7 @@ namespace IW4MAdmin.Application.EventParsers
Configuration.Damage.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12);
Configuration.Damage.AddMapping(ParserRegex.GroupType.HitLocation, 13);
Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
Configuration.Kill.AddMapping(ParserRegex.GroupType.EventType, 1);
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);

View File

@ -939,7 +939,7 @@ namespace IW4MAdmin
RemoteConnection.SetConfiguration(RconParser.Configuration);
var version = await this.GetDvarAsync<string>("version");
var version = await this.GetMappedDvarValueOrDefaultAsync<string>("version");
Version = version.Value;
GameName = Utilities.GetGame(version?.Value ?? RconParser.Version);
@ -956,8 +956,7 @@ namespace IW4MAdmin
Version = RconParser.Version;
}
// these T7 specific things aren't ideal , but it's a quick fix
var svRunning = await this.GetDvarAsync("sv_running", GameName == Game.T7 ? "1" : null);
var svRunning = await this.GetMappedDvarValueOrDefaultAsync<string>("sv_running");
if (!string.IsNullOrEmpty(svRunning.Value) && svRunning.Value != "1")
{
@ -965,29 +964,17 @@ namespace IW4MAdmin
}
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
var hostname = infoResponse == null ?
(await this.GetDvarAsync<string>("sv_hostname")).Value :
infoResponse.Where(kvp => kvp.Key.Contains("hostname")).Select(kvp => kvp.Value).First();
var mapname = infoResponse == null ?
(await this.GetDvarAsync("mapname", "Unknown")).Value :
infoResponse["mapname"];
int maxplayers = (GameName == Game.IW4) ? // gotta love IW4 idiosyncrasies
(await this.GetDvarAsync<int>("party_maxplayers")).Value :
infoResponse == null || !infoResponse.ContainsKey("sv_maxclients") ?
(await this.GetDvarAsync<int>("sv_maxclients")).Value :
Convert.ToInt32(infoResponse["sv_maxclients"]);
var gametype = infoResponse == null ?
(await this.GetDvarAsync("g_gametype", GameName == Game.T7 ? "" : null)).Value :
infoResponse.Where(kvp => kvp.Key.Contains("gametype")).Select(kvp => kvp.Value).First();
var basepath = await this.GetDvarAsync("fs_basepath", GameName == Game.T7 ? "" : null);
var basegame = await this.GetDvarAsync("fs_basegame", GameName == Game.T7 ? "" : null);
var game = infoResponse == null || !infoResponse.ContainsKey("fs_game") ?
(await this.GetDvarAsync("fs_game", GameName == Game.T7 ? "" : null)).Value :
infoResponse["fs_game"];
var logfile = await this.GetDvarAsync<string>("g_log");
var logsync = await this.GetDvarAsync<int>("g_logsync");
var ip = await this.GetDvarAsync<string>("net_ip");
string hostname = (await this.GetMappedDvarValueOrDefaultAsync<string>("sv_hostname", "hostname", infoResponse)).Value;
string mapname = (await this.GetMappedDvarValueOrDefaultAsync<string>("mapname", infoResponse: infoResponse)).Value;
int maxplayers = (await this.GetMappedDvarValueOrDefaultAsync<int>("sv_maxclients", infoResponse: infoResponse)).Value;
string gametype = (await this.GetMappedDvarValueOrDefaultAsync<string>("g_gametype", "gametype", infoResponse)).Value;
var basepath = (await this.GetMappedDvarValueOrDefaultAsync<string>("fs_basepath"));
var basegame = (await this.GetMappedDvarValueOrDefaultAsync<string>("fs_basegame"));
var game = (await this.GetMappedDvarValueOrDefaultAsync<string>("fs_game", infoResponse: infoResponse));
var logfile = await this.GetMappedDvarValueOrDefaultAsync<string>("g_log");
var logsync = await this.GetMappedDvarValueOrDefaultAsync<int>("g_logsync");
var ip = await this.GetMappedDvarValueOrDefaultAsync<string>("net_ip");
if (Manager.GetApplicationSettings().Configuration().EnableCustomSayName)
{
@ -996,7 +983,7 @@ namespace IW4MAdmin
try
{
var website = await this.GetDvarAsync<string>("_website");
var website = await this.GetMappedDvarValueOrDefaultAsync<string>("_website");
// this occurs for games that don't give us anything back when
// the dvar is not set
@ -1018,7 +1005,7 @@ namespace IW4MAdmin
WorkingDirectory = basepath.Value;
this.Hostname = hostname;
this.MaxClients = maxplayers;
this.FSGame = game;
this.FSGame = game.Value;
this.Gametype = gametype;
this.IP = ip.Value == "localhost" ? ServerConfig.IPAddress : ip.Value ?? ServerConfig.IPAddress;
UpdateMap(mapname);
@ -1070,7 +1057,7 @@ namespace IW4MAdmin
BaseGameDirectory = basegame.Value,
BasePathDirectory = basepath.Value,
GameDirectory = EventParser.Configuration.GameDirectory ?? "",
ModDirectory = game ?? "",
ModDirectory = game.Value ?? "",
LogFile = logfile.Value,
IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
};

View File

@ -14,8 +14,6 @@ namespace IW4MAdmin.Application.RconParsers
{
public class BaseRConParser : IRConParser
{
private const int MAX_FAULTY_STATUS_LINES = 7;
public BaseRConParser(IParserRegexFactory parserRegexFactory)
{
Configuration = new DynamicRConParserConfiguration(parserRegexFactory)
@ -56,10 +54,14 @@ namespace IW4MAdmin.Application.RconParsers
Configuration.StatusHeader.Pattern = "num +score +ping +guid +name +lastmsg +address +qport +rate *";
Configuration.MapStatus.Pattern = @"map: (([a-z]|_|\d)+)";
Configuration.MapStatus.AddMapping(ParserRegex.GroupType.RConStatusMap, 1);
if (!Configuration.DefaultDvarValues.ContainsKey("mapname"))
{
Configuration.DefaultDvarValues.Add("mapname", "Unknown");
}
}
public IRConParserConfiguration Configuration { get; set; }
public virtual string Version { get; set; } = "CoD";
public Game GameName { get; set; } = Game.COD;
public bool CanGenerateLogPath { get; set; } = true;
@ -211,14 +213,6 @@ namespace IW4MAdmin.Application.RconParsers
State = EFClient.ClientState.Connecting
};
//#if DEBUG
// if (client.NetworkId < 1000 && client.NetworkId > 0)
// {
// client.IPAddress = 2147483646;
// client.Ping = 0;
// }
//#endif
StatusPlayers.Add(client);
}
}
@ -231,5 +225,19 @@ namespace IW4MAdmin.Application.RconParsers
return StatusPlayers;
}
public string GetOverrideDvarName(string dvarName)
{
if (Configuration.OverrideDvarNameMapping.ContainsKey(dvarName))
{
return Configuration.OverrideDvarNameMapping[dvarName];
}
return dvarName;
}
public T GetDefaultDvarValue<T>(string dvarName) => Configuration.DefaultDvarValues.ContainsKey(dvarName) ?
(T)Convert.ChangeType(Configuration.DefaultDvarValues[dvarName], typeof(T)) :
default;
}
}

View File

@ -1,6 +1,6 @@
using IW4MAdmin.Application.Factories;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.RCon;
using System.Collections.Generic;
using System.Globalization;
namespace IW4MAdmin.Application.RconParsers
@ -19,6 +19,8 @@ namespace IW4MAdmin.Application.RconParsers
public string ServerNotRunningResponse { get; set; }
public bool WaitForResponse { get; set; } = true;
public NumberStyles GuidNumberStyle { get; set; } = NumberStyles.HexNumber;
public IDictionary<string, string> OverrideDvarNameMapping { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string> DefaultDvarValues { get; set; } = new Dictionary<string, string>();
public DynamicRConParserConfiguration(IParserRegexFactory parserRegexFactory)
{

View File

@ -3,7 +3,7 @@ var eventParser;
var plugin = {
author: 'RaidMax',
version: 0.1,
version: 0.2,
name: 'Black Ops 3 Parser',
isParser: true,
@ -24,6 +24,14 @@ var plugin = {
rconParser.Configuration.CommandPrefixes.RConSetDvar = '\xff\xff\xff\xff\x00{0} set {1}';
rconParser.Configuration.CommandPrefixes.RConResponse = '\xff\xff\xff\xff\x01';
rconParser.Configuration.CommandPrefixes.RConGetInfo = undefined; // disables this, because it's useless on T7
rconParser.Configuration.ServerNotRunningResponse = 'this is here to prevent a hiberating server from being detected as not running';
rconParser.Configuration.OverrideDvarNameMapping.Add('sv_hostname', 'live_steam_server_name');
rconParser.Configuration.DefaultDvarValues.Add('sv_running', '1');
rconParser.Configuration.DefaultDvarValues.Add('g_gametype', '');
rconParser.Configuration.DefaultDvarValues.Add('fs_basepath', '');
rconParser.Configuration.DefaultDvarValues.Add('fs_basegame', '');
rconParser.Configuration.DefaultDvarValues.Add('fs_game', '');
rconParser.Configuration.Status.AddMapping(105, 6); // ip address
rconParser.Version = '[local] ship win64 CODBUILD8-764 (3421987) Mon Dec 16 10:44:20 2019 10d27bef';
@ -34,7 +42,6 @@ var plugin = {
eventParser.GameName = 8; // BO3
eventParser.Configuration.GameDirectory = 'usermaps';
eventParser.Configuration.Say.Pattern = '^(chat|chatteam);(?:[0-9]+);([0-9]+);([0-9]+);(.+);(.*)$';
},
onUnloadAsync: function () {

View File

@ -3,7 +3,7 @@ var eventParser;
var plugin = {
author: 'RaidMax',
version: 0.5,
version: 0.6,
name: 'Tekno MW3 Parser',
isParser: true,
@ -27,6 +27,9 @@ var plugin = {
rconParser.Configuration.CommandPrefixes.TempBan = 'tempbanclient {0} "{1}"';
rconParser.Configuration.Dvar.AddMapping(107, 1); // RCon DvarValue
rconParser.Configuration.Dvar.Pattern = '^(.*)$';
rconParser.Configuration.DefaultDvarValues.Add('sv_running', '1');
rconParser.Version = 'IW5 MP 1.4 build 382 latest Thu Jan 19 2012 11:09:49AM win-x86';
rconParser.GameName = 3; // IW5
rconParser.CanGenerateLogPath = false;

View File

@ -63,8 +63,24 @@ namespace SharedLibraryCore.Interfaces
bool CanGenerateLogPath { get; set; }
/// <summary>
/// Specifies the name of the parser
/// specifies the name of the parser
/// </summary>
string Name { get; set; }
/// <summary>
/// retrieves the value of given dvar key if it exists in the override dict
/// otherwise returns original
/// </summary>
/// <param name="dvarName">name of dvar key</param>
/// <returns></returns>
string GetOverrideDvarName(string dvarName);
/// <summary>
/// retrieves the configuration value of a dvar key for
/// games that do not support the given dvar
/// </summary>
/// <param name="dvarName">dvar key name</param>
/// <returns></returns>
T GetDefaultDvarValue<T>(string dvarName);
}
}

View File

@ -1,4 +1,5 @@
using SharedLibraryCore.RCon;
using System.Collections.Generic;
using System.Globalization;
namespace SharedLibraryCore.Interfaces
@ -45,5 +46,16 @@ namespace SharedLibraryCore.Interfaces
/// indicates the format expected for parsed guids
/// </summary>
NumberStyles GuidNumberStyle { get; set; }
/// <summary>
/// specifies simple mappings for dvar names in scenarios where the needed
/// information is not stored in a traditional dvar name
/// </summary>
IDictionary<string, string> OverrideDvarNameMapping { get; set; }
/// <summary>
/// specifies the default dvar values for games that don't support certain dvars
/// </summary>
IDictionary<string, string> DefaultDvarValues { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SharedLibraryCore.Database.Models;

using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Helpers;
using SharedLibraryCore.Interfaces;
using System;
@ -747,7 +748,27 @@ namespace SharedLibraryCore
public static Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName, T fallbackValue = default)
{
return server.RconParser.GetDvarAsync<T>(server.RemoteConnection, dvarName, fallbackValue);
return server.RconParser.GetDvarAsync(server.RemoteConnection, dvarName, fallbackValue);
}
public static async Task<Dvar<T>> GetMappedDvarValueOrDefaultAsync<T>(this Server server, string dvarName, string infoResponseName = null, IDictionary<string, string> infoResponse = null)
{
// todo: unit test this
string mappedKey = server.RconParser.GetOverrideDvarName(dvarName);
var defaultValue = server.RconParser.GetDefaultDvarValue<T>(mappedKey);
string foundKey = infoResponse?.Keys.Where(_key => new[] { mappedKey, dvarName, infoResponseName ?? dvarName }.Contains(_key)).FirstOrDefault();
if (!string.IsNullOrEmpty(foundKey))
{
return new Dvar<T>
{
Value = (T)Convert.ChangeType(infoResponse[foundKey], typeof(T)),
Name = foundKey
};
}
return await server.GetDvarAsync(mappedKey, defaultValue);
}
public static Task SetDvarAsync(this Server server, string dvarName, object dvarValue)
@ -944,6 +965,8 @@ namespace SharedLibraryCore
public static bool ShouldHideLevel(this Permission perm) => perm == Permission.Flagged;
/// <summary>
/// replaces any directory separator chars with the platform specific character
/// </summary>