2018-11-25 21:00:36 -05:00
|
|
|
|
using SharedLibraryCore;
|
2020-07-31 21:40:03 -04:00
|
|
|
|
using SharedLibraryCore.Configuration;
|
2018-11-05 22:01:29 -05:00
|
|
|
|
using SharedLibraryCore.Database.Models;
|
2018-04-13 02:32:30 -04:00
|
|
|
|
using SharedLibraryCore.Interfaces;
|
2018-11-25 21:00:36 -05:00
|
|
|
|
using System;
|
2020-04-04 13:40:23 -04:00
|
|
|
|
using System.Collections.Generic;
|
2020-02-06 19:35:30 -05:00
|
|
|
|
using System.Linq;
|
2021-03-22 12:09:25 -04:00
|
|
|
|
using Data.Models;
|
2020-11-11 18:31:26 -05:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2019-02-05 19:02:45 -05:00
|
|
|
|
using static SharedLibraryCore.Server;
|
2020-11-11 18:31:26 -05:00
|
|
|
|
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
2018-04-13 02:32:30 -04:00
|
|
|
|
|
2018-04-25 02:38:59 -04:00
|
|
|
|
namespace IW4MAdmin.Application.EventParsers
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
2020-02-11 17:44:06 -05:00
|
|
|
|
public class BaseEventParser : IEventParser
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
2020-04-04 13:40:23 -04:00
|
|
|
|
private readonly Dictionary<string, (string, Func<string, IEventParserConfiguration, GameEvent, GameEvent>)> _customEventRegistrations;
|
|
|
|
|
private readonly ILogger _logger;
|
2020-07-31 21:40:03 -04:00
|
|
|
|
private readonly ApplicationConfiguration _appConfig;
|
2021-06-03 11:51:03 -04:00
|
|
|
|
private readonly Dictionary<ParserRegex, GameEvent.EventType> _regexMap;
|
|
|
|
|
private readonly Dictionary<string, GameEvent.EventType> _eventTypeMap;
|
2020-04-04 13:40:23 -04:00
|
|
|
|
|
2020-07-31 21:40:03 -04:00
|
|
|
|
public BaseEventParser(IParserRegexFactory parserRegexFactory, ILogger logger, ApplicationConfiguration appConfig)
|
2019-01-26 21:33:37 -05:00
|
|
|
|
{
|
2020-04-04 13:40:23 -04:00
|
|
|
|
_customEventRegistrations = new Dictionary<string, (string, Func<string, IEventParserConfiguration, GameEvent, GameEvent>)>();
|
|
|
|
|
_logger = logger;
|
2020-07-31 21:40:03 -04:00
|
|
|
|
_appConfig = appConfig;
|
2020-04-04 13:40:23 -04:00
|
|
|
|
|
2020-04-01 15:11:56 -04:00
|
|
|
|
Configuration = new DynamicEventParserConfiguration(parserRegexFactory)
|
2019-01-26 21:33:37 -05:00
|
|
|
|
{
|
2019-02-05 12:14:43 -05:00
|
|
|
|
GameDirectory = "main",
|
2022-11-03 20:58:29 -04:00
|
|
|
|
LocalizeText = "\x15",
|
2019-01-26 21:33:37 -05:00
|
|
|
|
};
|
2019-01-27 17:40:08 -05:00
|
|
|
|
|
2020-05-16 21:55:18 -04:00
|
|
|
|
Configuration.Say.Pattern = @"^(say|sayteam);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);([^;]*);(.*)$";
|
2019-02-02 20:40:37 -05:00
|
|
|
|
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);
|
2019-01-27 17:40:08 -05:00
|
|
|
|
|
2020-05-04 17:50:02 -04:00
|
|
|
|
Configuration.Quit.Pattern = @"^(Q);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);(.*)$";
|
2019-02-02 20:40:37 -05:00
|
|
|
|
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);
|
2019-01-27 17:40:08 -05:00
|
|
|
|
|
2020-05-04 17:50:02 -04:00
|
|
|
|
Configuration.Join.Pattern = @"^(J);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);(.*)$";
|
2019-02-02 20:40:37 -05:00
|
|
|
|
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);
|
2022-03-12 14:38:33 -05:00
|
|
|
|
|
|
|
|
|
Configuration.JoinTeam.Pattern = @"^(JT);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);(\w+);(.+)$";
|
|
|
|
|
Configuration.JoinTeam.AddMapping(ParserRegex.GroupType.EventType, 1);
|
|
|
|
|
Configuration.JoinTeam.AddMapping(ParserRegex.GroupType.OriginNetworkId, 2);
|
|
|
|
|
Configuration.JoinTeam.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3);
|
|
|
|
|
Configuration.JoinTeam.AddMapping(ParserRegex.GroupType.OriginTeam, 4);
|
|
|
|
|
Configuration.JoinTeam.AddMapping(ParserRegex.GroupType.OriginName, 5);
|
2019-01-27 17:40:08 -05:00
|
|
|
|
|
2021-12-23 14:12:12 -05:00
|
|
|
|
Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,32});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,32})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
|
2019-02-02 20:40:37 -05:00
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.EventType, 1);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetTeam, 4);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetName, 5);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.OriginNetworkId, 6);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.OriginClientNumber, 7);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.OriginTeam, 8);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.OriginName, 9);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.Weapon, 10);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.Damage, 11);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12);
|
|
|
|
|
Configuration.Damage.AddMapping(ParserRegex.GroupType.HitLocation, 13);
|
2019-01-27 17:40:08 -05:00
|
|
|
|
|
2021-12-23 14:12:12 -05:00
|
|
|
|
Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,32});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,32})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$";
|
2019-02-02 20:40:37 -05:00
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.EventType, 1);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetTeam, 4);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetName, 5);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.OriginNetworkId, 6);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.OriginClientNumber, 7);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.OriginTeam, 8);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.OriginName, 9);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.Weapon, 10);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.Damage, 11);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12);
|
|
|
|
|
Configuration.Kill.AddMapping(ParserRegex.GroupType.HitLocation, 13);
|
2020-04-01 15:11:56 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
Configuration.MapChange.Pattern = @".*InitGame.*";
|
|
|
|
|
Configuration.MapEnd.Pattern = @".*(?:ExitLevel|ShutdownGame).*";
|
|
|
|
|
|
2020-04-01 15:11:56 -04:00
|
|
|
|
Configuration.Time.Pattern = @"^ *(([0-9]+):([0-9]+) |^[0-9]+ )";
|
2021-06-03 11:51:03 -04:00
|
|
|
|
|
|
|
|
|
_regexMap = new Dictionary<ParserRegex, GameEvent.EventType>
|
|
|
|
|
{
|
|
|
|
|
{Configuration.Say, GameEvent.EventType.Say},
|
|
|
|
|
{Configuration.Kill, GameEvent.EventType.Kill},
|
|
|
|
|
{Configuration.MapChange, GameEvent.EventType.MapChange},
|
2022-03-28 19:05:18 -04:00
|
|
|
|
{Configuration.MapEnd, GameEvent.EventType.MapEnd},
|
|
|
|
|
{Configuration.JoinTeam, GameEvent.EventType.JoinTeam}
|
2021-06-03 11:51:03 -04:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_eventTypeMap = new Dictionary<string, GameEvent.EventType>
|
|
|
|
|
{
|
|
|
|
|
{"say", GameEvent.EventType.Say},
|
|
|
|
|
{"sayteam", GameEvent.EventType.Say},
|
2022-08-16 19:37:35 -04:00
|
|
|
|
{"chat", GameEvent.EventType.Say},
|
|
|
|
|
{"chatteam", GameEvent.EventType.Say},
|
2021-06-03 11:51:03 -04:00
|
|
|
|
{"K", GameEvent.EventType.Kill},
|
|
|
|
|
{"D", GameEvent.EventType.Damage},
|
|
|
|
|
{"J", GameEvent.EventType.PreConnect},
|
2022-03-28 19:05:18 -04:00
|
|
|
|
{"JT", GameEvent.EventType.JoinTeam},
|
|
|
|
|
{"Q", GameEvent.EventType.PreDisconnect}
|
2021-06-03 11:51:03 -04:00
|
|
|
|
};
|
2019-01-26 21:33:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-27 19:41:54 -05:00
|
|
|
|
public IEventParserConfiguration Configuration { get; set; }
|
2018-07-04 22:09:42 -04:00
|
|
|
|
|
2019-02-05 12:14:43 -05:00
|
|
|
|
public string Version { get; set; } = "CoD";
|
2019-02-02 19:54:30 -05:00
|
|
|
|
|
2019-02-05 19:02:45 -05:00
|
|
|
|
public Game GameName { get; set; } = Game.COD;
|
|
|
|
|
|
2019-04-06 22:48:49 -04:00
|
|
|
|
public string URLProtocolFormat { get; set; } = "CoD://{{ip}}:{{port}}";
|
|
|
|
|
|
2020-01-21 19:08:18 -05:00
|
|
|
|
public string Name { get; set; } = "Call of Duty";
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
private (GameEvent.EventType type, string eventKey) GetEventTypeFromLine(string logLine)
|
|
|
|
|
{
|
|
|
|
|
var lineSplit = logLine.Split(';');
|
|
|
|
|
if (lineSplit.Length > 1)
|
|
|
|
|
{
|
|
|
|
|
var type = lineSplit[0];
|
2021-06-16 09:51:22 -04:00
|
|
|
|
return _eventTypeMap.ContainsKey(type) ? (_eventTypeMap[type], type): (GameEvent.EventType.Unknown, lineSplit[0]);
|
2021-06-03 11:51:03 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var (key, value) in _regexMap)
|
|
|
|
|
{
|
|
|
|
|
var result = key.PatternMatcher.Match(logLine);
|
|
|
|
|
if (result.Success)
|
|
|
|
|
{
|
|
|
|
|
return (value, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (GameEvent.EventType.Unknown, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-05-13 11:36:11 -04:00
|
|
|
|
public virtual GameEvent GenerateGameEvent(string logLine)
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
2020-04-01 15:11:56 -04:00
|
|
|
|
var timeMatch = Configuration.Time.PatternMatcher.Match(logLine);
|
2020-12-13 21:33:37 -05:00
|
|
|
|
var gameTime = 0L;
|
2020-04-01 15:11:56 -04:00
|
|
|
|
|
2020-02-06 19:35:30 -05:00
|
|
|
|
if (timeMatch.Success)
|
|
|
|
|
{
|
2020-12-13 21:33:37 -05:00
|
|
|
|
if (timeMatch.Values[0].Contains(":"))
|
|
|
|
|
{
|
|
|
|
|
gameTime = timeMatch
|
|
|
|
|
.Values
|
|
|
|
|
.Skip(2)
|
|
|
|
|
// this converts the timestamp into seconds passed
|
2021-06-03 11:51:03 -04:00
|
|
|
|
.Select((value, index) => long.Parse(value.ToString()) * (index == 0 ? 60 : 1))
|
2020-12-13 21:33:37 -05:00
|
|
|
|
.Sum();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gameTime = long.Parse(timeMatch.Values[0]);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 15:11:56 -04:00
|
|
|
|
// we want to strip the time from the log line
|
2021-06-03 11:51:03 -04:00
|
|
|
|
logLine = logLine.Substring(timeMatch.Values.First().Length).Trim();
|
2020-04-01 15:11:56 -04:00
|
|
|
|
}
|
2020-02-06 19:35:30 -05:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var eventParseResult = GetEventTypeFromLine(logLine);
|
|
|
|
|
var eventType = eventParseResult.type;
|
|
|
|
|
|
|
|
|
|
_logger.LogDebug(logLine);
|
2018-04-13 02:32:30 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.Say)
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
2020-04-01 15:11:56 -04:00
|
|
|
|
var matchResult = Configuration.Say.PatternMatcher.Match(logLine);
|
2018-05-10 01:34:29 -04:00
|
|
|
|
|
2018-07-04 22:09:42 -04:00
|
|
|
|
if (matchResult.Success)
|
2018-05-10 01:34:29 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var message = matchResult.Values[Configuration.Say.GroupMapping[ParserRegex.GroupType.Message]]
|
2022-11-03 20:58:29 -04:00
|
|
|
|
.Replace(Configuration.LocalizeText, "")
|
2018-07-04 22:09:42 -04:00
|
|
|
|
.Trim();
|
|
|
|
|
|
2019-05-02 23:33:38 -04:00
|
|
|
|
if (message.Length > 0)
|
2018-07-04 22:09:42 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originIdString = matchResult.Values[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginNetworkId]];
|
|
|
|
|
var originName = matchResult.Values[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginName]];
|
2020-05-04 17:50:02 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originId = originIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
originName.GenerateGuidFromString() :
|
|
|
|
|
originIdString.ConvertGuidToLong(Configuration.GuidNumberStyle);
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var clientNumber = int.Parse(matchResult.Values[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginClientNumber]]);
|
2019-05-02 23:33:38 -04:00
|
|
|
|
|
2020-07-31 21:40:03 -04:00
|
|
|
|
if (message.StartsWith(_appConfig.CommandPrefix) || message.StartsWith(_appConfig.BroadcastCommandPrefix))
|
2019-05-02 23:33:38 -04:00
|
|
|
|
{
|
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Command,
|
|
|
|
|
Data = message,
|
2020-04-01 15:11:56 -04:00
|
|
|
|
Origin = new EFClient() { NetworkId = originId, ClientNumber = clientNumber },
|
2019-05-29 17:55:35 -04:00
|
|
|
|
Message = message,
|
2019-10-18 14:39:21 -04:00
|
|
|
|
Extra = logLine,
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.Origin,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2019-05-02 23:33:38 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-04 22:09:42 -04:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
2019-05-02 23:33:38 -04:00
|
|
|
|
Type = GameEvent.EventType.Say,
|
2018-07-04 22:09:42 -04:00
|
|
|
|
Data = message,
|
2020-04-01 15:11:56 -04:00
|
|
|
|
Origin = new EFClient() { NetworkId = originId, ClientNumber = clientNumber },
|
2019-05-29 17:55:35 -04:00
|
|
|
|
Message = message,
|
2019-10-18 14:39:21 -04:00
|
|
|
|
Extra = logLine,
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.Origin,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2018-07-04 22:09:42 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
2018-05-10 01:34:29 -04:00
|
|
|
|
}
|
2018-04-13 02:32:30 -04:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.Kill)
|
2018-08-31 23:35:51 -04:00
|
|
|
|
{
|
2020-04-01 15:11:56 -04:00
|
|
|
|
var match = Configuration.Kill.PatternMatcher.Match(logLine);
|
2018-08-31 23:35:51 -04:00
|
|
|
|
|
2019-05-13 11:36:11 -04:00
|
|
|
|
if (match.Success)
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originIdString = match.Values[Configuration.Kill.GroupMapping[ParserRegex.GroupType.OriginNetworkId]];
|
|
|
|
|
var targetIdString = match.Values[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetNetworkId]];
|
|
|
|
|
var originName = match.Values[Configuration.Kill.GroupMapping[ParserRegex.GroupType.OriginName]];
|
|
|
|
|
var targetName = match.Values[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetName]];
|
2020-05-04 17:50:02 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originId = originIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
originName.GenerateGuidFromString() :
|
|
|
|
|
originIdString.ConvertGuidToLong(Configuration.GuidNumberStyle, Utilities.WORLD_ID);
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var targetId = targetIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
targetName.GenerateGuidFromString() :
|
|
|
|
|
targetIdString.ConvertGuidToLong(Configuration.GuidNumberStyle, Utilities.WORLD_ID);
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originClientNumber = int.Parse(match.Values[Configuration.Kill.GroupMapping[ParserRegex.GroupType.OriginClientNumber]]);
|
|
|
|
|
var targetClientNumber = int.Parse(match.Values[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetClientNumber]]);
|
2018-04-13 02:32:30 -04:00
|
|
|
|
|
2019-05-13 11:36:11 -04:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Kill,
|
|
|
|
|
Data = logLine,
|
2020-04-01 15:11:56 -04:00
|
|
|
|
Origin = new EFClient() { NetworkId = originId, ClientNumber = originClientNumber },
|
|
|
|
|
Target = new EFClient() { NetworkId = targetId, ClientNumber = targetClientNumber },
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.Origin | GameEvent.EventRequiredEntity.Target,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2019-05-13 11:36:11 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
2018-05-08 00:58:46 -04:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.Damage)
|
2018-05-03 01:25:49 -04:00
|
|
|
|
{
|
2020-04-01 15:11:56 -04:00
|
|
|
|
var match = Configuration.Damage.PatternMatcher.Match(logLine);
|
2019-01-27 17:40:08 -05:00
|
|
|
|
|
2020-04-01 15:11:56 -04:00
|
|
|
|
if (match.Success)
|
2019-05-29 17:55:35 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originIdString = match.Values[Configuration.Damage.GroupMapping[ParserRegex.GroupType.OriginNetworkId]];
|
|
|
|
|
var targetIdString = match.Values[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetNetworkId]];
|
|
|
|
|
var originName = match.Values[Configuration.Damage.GroupMapping[ParserRegex.GroupType.OriginName]];
|
|
|
|
|
var targetName = match.Values[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetName]];
|
2020-05-04 17:50:02 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originId = originIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
originName.GenerateGuidFromString() :
|
|
|
|
|
originIdString.ConvertGuidToLong(Configuration.GuidNumberStyle, Utilities.WORLD_ID);
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var targetId = targetIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
targetName.GenerateGuidFromString() :
|
|
|
|
|
targetIdString.ConvertGuidToLong(Configuration.GuidNumberStyle, Utilities.WORLD_ID);
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originClientNumber = int.Parse(match.Values[Configuration.Damage.GroupMapping[ParserRegex.GroupType.OriginClientNumber]]);
|
|
|
|
|
var targetClientNumber = int.Parse(match.Values[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetClientNumber]]);
|
2018-09-02 17:59:27 -04:00
|
|
|
|
|
2019-05-29 17:55:35 -04:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Damage,
|
|
|
|
|
Data = logLine,
|
2020-04-01 15:11:56 -04:00
|
|
|
|
Origin = new EFClient() { NetworkId = originId, ClientNumber = originClientNumber },
|
|
|
|
|
Target = new EFClient() { NetworkId = targetId, ClientNumber = targetClientNumber },
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.Origin | GameEvent.EventRequiredEntity.Target,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2019-05-29 17:55:35 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
2018-05-03 01:25:49 -04:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.PreConnect)
|
2018-06-07 22:19:12 -04:00
|
|
|
|
{
|
2020-04-01 15:11:56 -04:00
|
|
|
|
var match = Configuration.Join.PatternMatcher.Match(logLine);
|
2019-05-13 11:36:11 -04:00
|
|
|
|
|
2020-04-01 15:11:56 -04:00
|
|
|
|
if (match.Success)
|
2018-06-07 22:19:12 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originIdString = match.Values[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]];
|
|
|
|
|
var originName = match.Values[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginName]];
|
2020-05-04 17:50:02 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var networkId = originIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
originName.GenerateGuidFromString() :
|
|
|
|
|
originIdString.ConvertGuidToLong(Configuration.GuidNumberStyle);
|
|
|
|
|
|
2018-06-07 22:19:12 -04:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
2018-11-07 21:30:11 -05:00
|
|
|
|
Type = GameEvent.EventType.PreConnect,
|
2018-06-30 21:55:16 -04:00
|
|
|
|
Data = logLine,
|
2018-11-05 22:01:29 -05:00
|
|
|
|
Origin = new EFClient()
|
2018-06-07 22:19:12 -04:00
|
|
|
|
{
|
2018-11-25 21:00:36 -05:00
|
|
|
|
CurrentAlias = new EFAlias()
|
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
Name = match.Values[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginName]].TrimNewLine(),
|
2018-11-25 21:00:36 -05:00
|
|
|
|
},
|
2020-05-04 17:50:02 -04:00
|
|
|
|
NetworkId = networkId,
|
2021-06-03 11:51:03 -04:00
|
|
|
|
ClientNumber = Convert.ToInt32(match.Values[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginClientNumber]]),
|
2018-11-05 22:01:29 -05:00
|
|
|
|
State = EFClient.ClientState.Connecting,
|
2019-05-29 17:55:35 -04:00
|
|
|
|
},
|
2020-09-21 16:30:42 -04:00
|
|
|
|
Extra = originIdString,
|
2019-10-18 14:39:21 -04:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.None,
|
2020-02-06 19:35:30 -05:00
|
|
|
|
IsBlocking = true,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2018-06-07 22:19:12 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 14:38:33 -05:00
|
|
|
|
if (eventType == GameEvent.EventType.JoinTeam)
|
|
|
|
|
{
|
|
|
|
|
var match = Configuration.JoinTeam.PatternMatcher.Match(logLine);
|
|
|
|
|
|
|
|
|
|
if (match.Success)
|
|
|
|
|
{
|
|
|
|
|
var originIdString = match.Values[Configuration.JoinTeam.GroupMapping[ParserRegex.GroupType.OriginNetworkId]];
|
|
|
|
|
var originName = match.Values[Configuration.JoinTeam.GroupMapping[ParserRegex.GroupType.OriginName]];
|
|
|
|
|
var team = match.Values[Configuration.JoinTeam.GroupMapping[ParserRegex.GroupType.OriginTeam]];
|
|
|
|
|
|
2022-03-28 19:05:18 -04:00
|
|
|
|
if (Configuration.TeamMapping.ContainsKey(team))
|
|
|
|
|
{
|
|
|
|
|
team = Configuration.TeamMapping[team].ToString();
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 14:38:33 -05:00
|
|
|
|
var networkId = originIdString.IsBotGuid() ?
|
|
|
|
|
originName.GenerateGuidFromString() :
|
|
|
|
|
originIdString.ConvertGuidToLong(Configuration.GuidNumberStyle);
|
|
|
|
|
|
|
|
|
|
return new GameEvent
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.JoinTeam,
|
|
|
|
|
Data = logLine,
|
|
|
|
|
Origin = new EFClient
|
|
|
|
|
{
|
|
|
|
|
CurrentAlias = new EFAlias
|
|
|
|
|
{
|
|
|
|
|
Name = match.Values[Configuration.JoinTeam.GroupMapping[ParserRegex.GroupType.OriginName]].TrimNewLine(),
|
|
|
|
|
},
|
|
|
|
|
NetworkId = networkId,
|
|
|
|
|
ClientNumber = Convert.ToInt32(match.Values[Configuration.JoinTeam.GroupMapping[ParserRegex.GroupType.OriginClientNumber]]),
|
|
|
|
|
State = EFClient.ClientState.Connected,
|
|
|
|
|
},
|
|
|
|
|
Extra = team,
|
2022-03-25 14:16:41 -04:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.Origin,
|
2022-03-12 14:38:33 -05:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.PreDisconnect)
|
2018-11-07 21:30:11 -05:00
|
|
|
|
{
|
2020-04-01 15:11:56 -04:00
|
|
|
|
var match = Configuration.Quit.PatternMatcher.Match(logLine);
|
|
|
|
|
|
|
|
|
|
if (match.Success)
|
2018-11-07 21:30:11 -05:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var originIdString = match.Values[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginNetworkId]];
|
|
|
|
|
var originName = match.Values[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginName]];
|
2020-05-04 17:50:02 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var networkId = originIdString.IsBotGuid() ?
|
2020-05-04 17:50:02 -04:00
|
|
|
|
originName.GenerateGuidFromString() :
|
|
|
|
|
originIdString.ConvertGuidToLong(Configuration.GuidNumberStyle);
|
|
|
|
|
|
2018-11-07 21:30:11 -05:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.PreDisconnect,
|
|
|
|
|
Data = logLine,
|
|
|
|
|
Origin = new EFClient()
|
|
|
|
|
{
|
2018-11-25 21:00:36 -05:00
|
|
|
|
CurrentAlias = new EFAlias()
|
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
Name = match.Values[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginName]].TrimNewLine()
|
2018-11-25 21:00:36 -05:00
|
|
|
|
},
|
2020-05-04 17:50:02 -04:00
|
|
|
|
NetworkId = networkId,
|
2021-06-03 11:51:03 -04:00
|
|
|
|
ClientNumber = Convert.ToInt32(match.Values[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginClientNumber]]),
|
2018-11-07 21:30:11 -05:00
|
|
|
|
State = EFClient.ClientState.Disconnecting
|
2019-05-29 17:55:35 -04:00
|
|
|
|
},
|
2019-10-18 14:39:21 -04:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.None,
|
2020-02-06 19:35:30 -05:00
|
|
|
|
IsBlocking = true,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2018-11-07 21:30:11 -05:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-30 21:55:16 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.MapEnd)
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.MapEnd,
|
2019-10-18 14:39:21 -04:00
|
|
|
|
Data = logLine,
|
2019-05-13 11:36:11 -04:00
|
|
|
|
Origin = Utilities.IW4MAdminClient(),
|
|
|
|
|
Target = Utilities.IW4MAdminClient(),
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.None,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2018-04-13 02:32:30 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventType == GameEvent.EventType.MapChange)
|
2018-04-13 02:32:30 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
var dump = logLine.Replace("InitGame: ", "");
|
2018-04-23 01:43:48 -04:00
|
|
|
|
|
2018-04-13 02:32:30 -04:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.MapChange,
|
2019-10-18 14:39:21 -04:00
|
|
|
|
Data = logLine,
|
2019-05-13 11:36:11 -04:00
|
|
|
|
Origin = Utilities.IW4MAdminClient(),
|
|
|
|
|
Target = Utilities.IW4MAdminClient(),
|
2019-05-29 17:55:35 -04:00
|
|
|
|
Extra = dump.DictionaryFromKeyValue(),
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.None,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2018-04-13 02:32:30 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
if (eventParseResult.eventKey == null || !_customEventRegistrations.ContainsKey(eventParseResult.eventKey))
|
2019-05-13 11:36:11 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
return new GameEvent()
|
2019-05-13 11:36:11 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
Type = GameEvent.EventType.Unknown,
|
|
|
|
|
Data = logLine,
|
|
|
|
|
Origin = Utilities.IW4MAdminClient(),
|
|
|
|
|
Target = Utilities.IW4MAdminClient(),
|
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.None,
|
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var eventModifier = _customEventRegistrations[eventParseResult.eventKey];
|
2019-05-13 11:36:11 -04:00
|
|
|
|
|
2021-06-03 11:51:03 -04:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return eventModifier.Item2(logLine, Configuration, new GameEvent()
|
2019-05-13 11:36:11 -04:00
|
|
|
|
{
|
2021-06-03 11:51:03 -04:00
|
|
|
|
Type = GameEvent.EventType.Other,
|
|
|
|
|
Data = logLine,
|
|
|
|
|
Subtype = eventModifier.Item1,
|
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(e, "Could not handle custom event generation");
|
2019-05-13 11:36:11 -04:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 02:32:30 -04:00
|
|
|
|
return new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Unknown,
|
2019-06-30 14:37:59 -04:00
|
|
|
|
Data = logLine,
|
2019-05-13 11:36:11 -04:00
|
|
|
|
Origin = Utilities.IW4MAdminClient(),
|
2019-05-29 17:55:35 -04:00
|
|
|
|
Target = Utilities.IW4MAdminClient(),
|
2020-02-06 19:35:30 -05:00
|
|
|
|
RequiredEntity = GameEvent.EventRequiredEntity.None,
|
2020-05-04 17:50:02 -04:00
|
|
|
|
GameTime = gameTime,
|
|
|
|
|
Source = GameEvent.EventSource.Log
|
2018-04-13 02:32:30 -04:00
|
|
|
|
};
|
|
|
|
|
}
|
2020-04-04 13:40:23 -04:00
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
public void RegisterCustomEvent(string eventSubtype, string eventTriggerValue, Func<string, IEventParserConfiguration, GameEvent, GameEvent> eventModifier)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(eventSubtype))
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Event subtype cannot be empty");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(eventTriggerValue))
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Event trigger value cannot be empty");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (eventModifier == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Event modifier must be specified");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_customEventRegistrations.ContainsKey(eventTriggerValue))
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException($"Event trigger value '{eventTriggerValue}' is already registered");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_customEventRegistrations.Add(eventTriggerValue, (eventSubtype, eventModifier));
|
|
|
|
|
}
|
2018-04-13 02:32:30 -04:00
|
|
|
|
}
|
|
|
|
|
}
|