Skip to content

Commit

Permalink
fix reading PT6 having signed decimal GUID in log
Browse files Browse the repository at this point in the history
fix  alternative encoding character converting
allow more paths for game log server
add localization for unknown ips in welcome plugin
add gamelog server uri to support game log server on games that must supply manual log path
misc fixes
  • Loading branch information
RaidMax committed Feb 9, 2019
1 parent 2714f50 commit a2ce191
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 66 deletions.
6 changes: 3 additions & 3 deletions Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
<Version>2.2.4.6</Version>
<Version>2.2.4.7</Version>
<Authors>RaidMax</Authors>
<Company>Forever None</Company>
<Product>IW4MAdmin</Product>
Expand All @@ -31,8 +31,8 @@
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>true</TieredCompilation>
<AssemblyVersion>2.2.4.6</AssemblyVersion>
<FileVersion>2.2.4.6</FileVersion>
<AssemblyVersion>2.2.4.7</AssemblyVersion>
<FileVersion>2.2.4.7</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 3 additions & 1 deletion Application/ApplicationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ public async Task Init()

foreach (var serverConfig in config.Servers)
{
Migration.ConfigurationMigration.ModifyLogPath020919(serverConfig);

if (serverConfig.RConParserVersion == null || serverConfig.EventParserVersion == null)
{
foreach (var parser in AdditionalRConParsers)
Expand All @@ -299,8 +301,8 @@ public async Task Init()
}

serverConfig.ModifyParsers();
await ConfigHandler.Save();
}
await ConfigHandler.Save();
}
}

Expand Down
10 changes: 5 additions & 5 deletions Application/EventParsers/BaseEventParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,26 @@ public BaseEventParser()
GameDirectory = "main",
};

Configuration.Say.Pattern = @"^(say|sayteam);(.{8,32});([0-9]+);(.+);(.*)$";
Configuration.Say.Pattern = @"^(say|sayteam);(-?[A-Fa-f0-9_]{8,32});([0-9]+);(.+);(.*)$";
Configuration.Say.AddMapping(ParserRegex.GroupType.EventType, 1);
Configuration.Say.AddMapping(ParserRegex.GroupType.OriginNetworkId, 2);
Configuration.Say.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
Configuration.Say.AddMapping(ParserRegex.GroupType.OriginName, 4);
Configuration.Say.AddMapping(ParserRegex.GroupType.Message, 5);

Configuration.Quit.Pattern = @"^(Q);(.{8,32}|bot[0-9]+);([0-9]+);(.*)$";
Configuration.Quit.Pattern = @"^(Q);(-?[A-Fa-f0-9_]{8,32}|bot[0-9]+);([0-9]+);(.*)$";
Configuration.Quit.AddMapping(ParserRegex.GroupType.EventType, 1);
Configuration.Quit.AddMapping(ParserRegex.GroupType.OriginNetworkId, 2);
Configuration.Quit.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
Configuration.Quit.AddMapping(ParserRegex.GroupType.OriginName, 4);

Configuration.Join.Pattern = @"^(J);(.{8,32}|bot[0-9]+);([0-9]+);(.*)$";
Configuration.Join.Pattern = @"^(J);(-?[A-Fa-f0-9_]{8,32}|bot[0-9]+);([0-9]+);(.*)$";
Configuration.Join.AddMapping(ParserRegex.GroupType.EventType, 1);
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginNetworkId, 2);
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
Configuration.Join.AddMapping(ParserRegex.GroupType.OriginName, 4);

Configuration.Damage.Pattern = @"^(D);([A-Fa-f0-9_]{8,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world);(.{1,24});([A-Fa-f0-9_]{8,32}|bot[0-9]+)?;-?([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_]{8,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world);(.{1,24});(-?[A-Fa-f0-9_]{8,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world);(.{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);
Expand All @@ -51,7 +51,7 @@ public BaseEventParser()
Configuration.Damage.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12);
Configuration.Damage.AddMapping(ParserRegex.GroupType.HitLocation, 13);

Configuration.Kill.Pattern = @"^(K);([A-Fa-f0-9_]{8,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world);(.{1,24});([A-Fa-f0-9_]{8,32}|bot[0-9]+)?;-?([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_]{8,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world);(.{1,24});(-?[A-Fa-f0-9_]{8,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world);(.{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);
Expand Down
13 changes: 2 additions & 11 deletions Application/IO/GameLogEventDetection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,10 @@ class EventState
public string ServerId { get; set; }
}

public GameLogEventDetection(Server server, string gameLogPath, string gameLogName)
public GameLogEventDetection(Server server, string gameLogPath, Uri gameLogServerUri)
{
GameLogFile = gameLogPath;
// todo: abtract this more
if (gameLogPath.StartsWith("http"))
{
Reader = new GameLogReaderHttp(gameLogPath, server.EventParser);
}
else
{
Reader = new GameLogReader(gameLogPath, server.EventParser);
}

Reader = gameLogServerUri != null ? new GameLogReaderHttp(gameLogServerUri, gameLogPath, server.EventParser) : Reader = new GameLogReader(gameLogPath, server.EventParser);
Server = server;
}

Expand Down
12 changes: 6 additions & 6 deletions Application/IO/GameLogReaderHttp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ class GameLogReaderHttp : IGameLogReader
{
readonly IEventParser Parser;
readonly IGameLogServer Api;
readonly string LogFile;
readonly string logPath;

public GameLogReaderHttp(string logFile, IEventParser parser)
public GameLogReaderHttp(Uri gameLogServerUri, string logPath, IEventParser parser)
{
LogFile = logFile;
this.logPath = logPath.ToBase64UrlSafeString(); ;
Parser = parser;
Api = RestClient.For<IGameLogServer>(logFile);
Api = RestClient.For<IGameLogServer>(gameLogServerUri);
}

public long Length => -1;
Expand All @@ -36,12 +36,12 @@ public async Task<ICollection<GameEvent>> ReadEventsFromLog(Server server, long
server.Logger.WriteDebug($"Begin reading from http log");
#endif
var events = new List<GameEvent>();
string b64Path = server.LogPath.ToBase64UrlSafeString();
string b64Path = logPath;
var response = await Api.Log(b64Path);

if (!response.Success)
{
server.Logger.WriteError($"Could not get log server info of {LogFile}/{b64Path} ({server.LogPath})");
server.Logger.WriteError($"Could not get log server info of {logPath}/{b64Path} ({server.LogPath})");
return events;
}

Expand Down
41 changes: 15 additions & 26 deletions Application/IW4MServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -750,47 +750,36 @@ public async Task Initialize()
}

CustomCallback = await ScriptLoaded();
string mainPath = EventParser.Configuration.GameDirectory;
string logPath = string.Empty;

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)

// they've manually specified the log path
if (!string.IsNullOrEmpty(ServerConfig.ManualLogPath))
{
logPath = ServerConfig.ManualLogPath;
remoteLog = logPath.StartsWith("http");
LogPath = ServerConfig.ManualLogPath;
}

else
{
logPath = LogPath;
}
string mainPath = EventParser.Configuration.GameDirectory;

if (remoteLog)
{
LogEvent = new GameLogEventDetection(this, logPath, 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}";

else
{
// fix wine drive name mangling
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
logPath = Regex.Replace($"{Path.DirectorySeparatorChar}{LogPath}", @"[A-Z]:/", "");
LogPath = Regex.Replace($"{Path.DirectorySeparatorChar}{LogPath}", @"[A-Z]:/", "");
}

if (!File.Exists(logPath))
if (!File.Exists(LogPath))
{
Logger.WriteError($"{logPath} {loc["SERVER_ERROR_DNE"]}");
throw new ServerException($"{loc["SERVER_ERROR_LOG"]} {logPath}");
Logger.WriteError($"{LogPath} {loc["SERVER_ERROR_DNE"]}");
throw new ServerException($"{loc["SERVER_ERROR_LOG"]} {LogPath}");
}

LogEvent = new GameLogEventDetection(this, logPath, logfile.Value);
}

Logger.WriteInfo($"Log file is {logPath}");
LogEvent = new GameLogEventDetection(this, LogPath, ServerConfig.GameLogServerUrl);
Logger.WriteInfo($"Log file is {LogPath}");

_ = Task.Run(() => LogEvent.PollForChanges());
#if !DEBUG
Expand Down
9 changes: 9 additions & 0 deletions Application/Migration/ConfigurationMigration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,14 @@ public static void MoveConfigFolder10518(ILogger log)
}
}
}

public static void ModifyLogPath020919(SharedLibraryCore.Configuration.ServerConfiguration config)
{
if (config.ManualLogPath.IsRemoteLog())
{
config.GameLogServerUrl = new Uri(config.ManualLogPath);
config.ManualLogPath = null;
}
}
}
}
2 changes: 1 addition & 1 deletion Application/RconParsers/BaseRConParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public async Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarNam

public async Task<List<EFClient>> GetStatusAsync(Connection connection)
{
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND_STATUS);
return ClientsFromStatus(response);
}

Expand Down
4 changes: 3 additions & 1 deletion GameLogServer/GameLogServer.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<LaunchProvider>Web launcher</LaunchProvider>
<LaunchProvider>Standard Python launcher</LaunchProvider>
<WebBrowserUrl>http://localhost</WebBrowserUrl>
<OutputPath>.</OutputPath>
<SuppressCollectPythonCloudServiceFiles>true</SuppressCollectPythonCloudServiceFiles>
<Name>GameLogServer</Name>
<RootNamespace>GameLogServer</RootNamespace>
<InterpreterId>MSBuild|env|$(MSBuildProjectFullPath)</InterpreterId>
<EnableNativeCodeDebugging>False</EnableNativeCodeDebugging>
<Environment>DEBUG=True</Environment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
Expand Down
2 changes: 1 addition & 1 deletion GameLogServer/GameLogServer/log_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def read_file(self, path):
if re.search('r^.+\.\.\\.+$', path):
return False
# must be a valid log path and log file
if not re.search(r'^.+[\\|\/](userraw|mods|main)[\\|\/].+.log$', path):
if not re.search(r'^.+[\\|\/](.+)[\\|\/].+.log$', path):
return False
# set the initialze size to the current file size
file_size = 0
Expand Down
5 changes: 3 additions & 2 deletions Plugins/Welcome/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,14 @@ private async Task<string> GetCountryName(string ip)
{
string response = await wc.DownloadStringTaskAsync(new Uri($"http://extreme-ip-lookup.com/json/{ip}"));
var responseObj = JObject.Parse(response);
response = responseObj["country"].ToString();

return responseObj["country"].ToString();
return string.IsNullOrEmpty(response) ? Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_WELCOME_UNKNOWN_COUNTRY"] : response;
}

catch
{
return "a third world country";
return Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_WELCOME_UNKNOWN_IP"];
}
}
}
Expand Down
1 change: 1 addition & 0 deletions SharedLibraryCore/Configuration/ServerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class ServerConfiguration : IBaseConfiguration
public string RConParserVersion { get; set; }
public string EventParserVersion { get; set; }
public int ReservedSlotNumber { get; set; }
public Uri GameLogServerUrl { get; set; }

private readonly IList<IRConParser> rconParsers;
private readonly IList<IEventParser> eventParsers;
Expand Down
18 changes: 10 additions & 8 deletions SharedLibraryCore/RCon/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,14 @@ public async Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string
byte[] payload = null;
bool waitForResponse = Config.WaitForResponse;

string converterEncoding(string text)
{
var destinationEncoding = Encoding.GetEncoding("windows-1252");
byte[] originalEncodedBytes = Utilities.EncodingType.GetBytes(text);
byte[] convertedBytes = Encoding.Convert(Utilities.EncodingType, destinationEncoding, originalEncodedBytes);
return destinationEncoding.GetString(convertedBytes);
string convertEncoding(string text)
{
byte[] convertedBytes = Utilities.EncodingType.GetBytes(text);
return Utilities.EncodingType.GetString(convertedBytes);
}

string convertedRConPassword = converterEncoding(RConPassword);
string convertedParameters = converterEncoding(parameters);
string convertedRConPassword = convertEncoding(RConPassword);
string convertedParameters = convertEncoding(parameters);

switch (type)
{
Expand All @@ -109,6 +107,10 @@ string converterEncoding(string text)
waitForResponse |= true;
payload = (Config.CommandPrefixes.RConGetInfo + '\0').Select(Convert.ToByte).ToArray();
break;
case StaticHelpers.QueryType.COMMAND_STATUS:
waitForResponse |= true;
payload = string.Format(Config.CommandPrefixes.RConCommand, convertedRConPassword, "status\0").Select(Convert.ToByte).ToArray();
break;
}

byte[] response = null;
Expand Down
5 changes: 5 additions & 0 deletions SharedLibraryCore/RCon/StaticHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public enum QueryType
/// RCon password is required
/// </summary>
COMMAND,
/// <summary>
/// get the full server command information
/// RCon password is required
/// </summary>
COMMAND_STATUS
}

/// <summary>
Expand Down
14 changes: 13 additions & 1 deletion SharedLibraryCore/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,16 @@ public static string GetLocalizedGametype(String input)
public static long ConvertLong(this string str)
{
str = str.Substring(0, Math.Min(str.Length, 16));
if (Int64.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out long id))
if (long.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out long id))
{
return id;
}

if (long.TryParse(str, NumberStyles.Integer, CultureInfo.InvariantCulture, out id))
{
return (uint)id;
}

var bot = Regex.Match(str, @"bot[0-9]+").Value;
if (!string.IsNullOrEmpty(bot))
{
Expand Down Expand Up @@ -640,6 +645,13 @@ public static string GetCommandLine(int pId)
return cmdLine.Length > 1 ? cmdLine[1] : cmdLine[0];
}

/// <summary>
/// indicates if the given log path is a remote (http) uri
/// </summary>
/// <param name="log"></param>
/// <returns></returns>
public static bool IsRemoteLog(this string log) => (log ?? "").StartsWith("http");

public static string ToBase64UrlSafeString(this string src)
{
return Convert.ToBase64String(src.Select(c => Convert.ToByte(c)).ToArray()).Replace('+', '-').Replace('/', '_');
Expand Down

0 comments on commit a2ce191

Please sign in to comment.