diff --git a/ModTek/Features/Logging/AppenderFile.cs b/ModTek/Features/Logging/AppenderFile.cs index 3a080a1f..6ce694a3 100644 --- a/ModTek/Features/Logging/AppenderFile.cs +++ b/ModTek/Features/Logging/AppenderFile.cs @@ -8,7 +8,7 @@ namespace ModTek.Features.Logging; internal class AppenderFile : IDisposable { - private readonly Filters _filters; + private readonly Filters.FilterDelegate _filters; private readonly Formatter _formatter; private readonly LogStream _writer; @@ -18,7 +18,7 @@ internal class AppenderFile : IDisposable internal AppenderFile(string path, AppenderSettings settings) { - _filters = new Filters(settings); + _filters = Filters.Compile(settings); _formatter = new Formatter(settings); FileUtils.CreateParentOfPath(path); @@ -63,7 +63,8 @@ internal void Append(ref MTLoggerMessageDto messageDto) { var measurement = MTStopwatch.GetTimestamp(); - var included = _filters.IsIncluded(ref messageDto); + //var included = _filters(ref messageDto); + var included = Filters.HardcodedFilter(ref messageDto); FiltersStopWatch.EndMeasurement(measurement); if (!included) { diff --git a/ModTek/Features/Logging/AppenderSettings.cs b/ModTek/Features/Logging/AppenderSettings.cs index 16171b45..0b3335d9 100644 --- a/ModTek/Features/Logging/AppenderSettings.cs +++ b/ModTek/Features/Logging/AppenderSettings.cs @@ -21,8 +21,67 @@ internal class AppenderSettings [JsonProperty] internal readonly string PrefixesToIgnore_Description = $"Ignore any lines starting with any of the listed prefixes, internally will be converted to {nameof(Excludes)}."; - [JsonProperty] - internal string[] PrefixesToIgnore; + + [JsonProperty] internal string[] PrefixesToIgnore = + [ + "Unity [ERROR] Desired shader compiler platform", + "Unity [LOG] Look rotation viewing vector is zero", + "Unity [ERROR] Material doesn't have a color property", + "Unity [WARNING] Parent of RectTransform is being set with parent property", + "Unity [WARNING] The referenced script", + "Unity [WARNING] Rejecting unit", + "Unity [WARNING] Parent of RectTransform is being set with parent property", + "Unity [WARNING] No DefaultCombatLeaderCastDefId specified for faction [Player1sMercUnit]", + "Unity [WARNING] No DefaultCombatLeaderCastDefId specified for faction [Player2sMercUnit]", + "Unity [ERROR] Bones do not match bindpose.", + "Unity [ERROR] ================== ERROR! Found missing transforms", + "Unity [WARNING] ERROR! Couldn't auto-setup", + "Unity [WARNING] Could not retrieve member", + "MapExport [ERROR] Out of bounds", + "CombatLog.Hit [LOG] ???????? DIRECTION:", + "Unity [WARNING] BoxColliders does not support negative scale or size", + "AudioEvents [DEBUG] Audio Engine", + "MechEngineer [LOG] Auto fixing chassisDef", + "AudioEvents [DEBUG] OnApplicationFocus", + "NetworkRandomValues [DEBUG] Seed", + "NetworkRandomCallstacks [DEBUG] Seed", + "UserSettings [DEBUG] Using existing cloud settings from save manager", + "BattleTech.Services [DEBUG] [BattleTechParadoxAPI]", + "Network.Client [LOG] Connection", + "GameInfo [LOG] DEVELOPMENT FLAG NOT SET", + "MechEngineer [LOG] settings loaded", + "GameInfo [LOG] ProductName: BATTLETECH", + "GameInfo [LOG] RELEASE FLAG SET", + "DebugBridge", + "CustomComponents [LOG] [CC]SimpleCustom", + "LoginManager [LOG] Successfully authenticated with OPS. Moving onto ComStar connection proper.", + "Data.AssetBundleManager [LOG] Trying to load AssetBundle:", + "UserSettings [LOG] [LOG] User settings saved", + "MechLab [WARNING] GetWeaponPrefabName failed to find a prefab name for unit", + "Analytics [WARNING] Analytics Event requested with invalid IP", + "Analytics [WARNING] Request next called but no servers have been found", + "Analytics [WARNING] Request next called but reporting is disabled", + "UI [WARNING] Singleton UIManagerFader", + "CombatLog.Initialization [WARNING] Turret", + "MechEngineer [WARNING] Unsupported weapon category for 667", + "MechEngineer [WARNING] Unsupported weapon category for 666", + "CustomComponents [DEBUG] [CC]Mech validation for NULL return", + "CustomComponents [DEBUG] [CC]-- CustomComponents.Flags", + "CustomComponents [DEBUG] [CC]-- CustomComponents.AutoLinked", + "CustomComponents.UnitType [DEBUG]", + "Data.DataManager [WARNING] LoadRequest for", + "LewdableTanks [DEBUG] Fixing cost of", + "CombatLog.Initialization [ERROR] Error instantiating VFX", + "PilotDef [WARNING] PilotDef already did Init From Save!", + "Achievements [LOG]", + "DataLoader [DEBUG] Loading:", + "Save.Core.SaveSystem [DEBUG]", + "Unity [ERROR] Generating SIM GAME UID while still loading!", + "Unity [WARNING] HBS Tooltip on UI Element", + "HarmonyX [TRACE]", + "HarmonyX [LOG]", + "Unity [ERROR] RenderTexture.Create failed: format unsupported for random writes" + ]; [JsonProperty] internal const string AbsoluteTimeEnabled_Description = "Adds the clock time."; diff --git a/ModTek/Features/Logging/AppenderUnityConsole.cs b/ModTek/Features/Logging/AppenderUnityConsole.cs index 9dbdf79f..a79edc3b 100644 --- a/ModTek/Features/Logging/AppenderUnityConsole.cs +++ b/ModTek/Features/Logging/AppenderUnityConsole.cs @@ -9,14 +9,14 @@ internal class AppenderUnityConsole { // appender part - private readonly Filters _filters; + private readonly Filters.FilterDelegate _filters; private readonly Formatter _formatter; private readonly ILogger _debugUnityLogger; private readonly FastBuffer _buffer = new(); internal AppenderUnityConsole(AppenderSettings settings) { - _filters = new Filters(settings); + _filters = Filters.Compile(settings); _formatter = new Formatter(settings); _debugUnityLogger = Debug.unityLogger; } @@ -35,7 +35,7 @@ internal void Append(ref MTLoggerMessageDto messageDto) return; } - if (!_filters.IsIncluded(ref messageDto)) + if (!_filters(ref messageDto)) { return; } diff --git a/ModTek/Features/Logging/Filter.cs b/ModTek/Features/Logging/Filter.cs deleted file mode 100644 index 6a3570a8..00000000 --- a/ModTek/Features/Logging/Filter.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Linq; -using System.Text.RegularExpressions; -using HBS.Logging; - -namespace ModTek.Features.Logging; - -internal class Filter -{ - private readonly string[] _loggerNames; - private readonly LogLevel[] _logLevels; - private readonly Regex _messagePrefixesMatcher; - - internal Filter(FilterSettings settings) - { - if (settings.LoggerNames != null) - { - // Intern allows us to use ReferenceEquals a.k.a == - // since logger names are already interned by LogImpl - _loggerNames = settings.LoggerNames.Select(string.Intern).ToArray(); - } - if (settings.LogLevels != null) - { - _logLevels = settings.LogLevels; - } - - if (settings.MessagePrefixes != null) - { - try - { - var trie = Trie.Create(settings.MessagePrefixes); - _messagePrefixesMatcher = trie.CompileRegex(); - } - catch (Exception e) - { - throw new Exception("Issue processing logging ignore prefixes", e); - } - } - } - - internal bool IsMatch(ref MTLoggerMessageDto messageDto) - { - if (_loggerNames != null) - { - var found = false; - foreach (var loggerName in _loggerNames) - { - if (ReferenceEquals(loggerName, messageDto.LoggerName)) - { - found = true; - break; - } - } - - if (!found) - { - return false; - } - } - - if (_logLevels != null) - { - var found = false; - foreach (var logLevel in _logLevels) - { - if (logLevel == messageDto.LogLevel) - { - found = true; - break; - } - } - - if (!found) - { - return false; - } - } - - if (_messagePrefixesMatcher != null && !_messagePrefixesMatcher.IsMatch(messageDto.Message)) - { - return false; - } - - return true; - } -} \ No newline at end of file diff --git a/ModTek/Features/Logging/Filters.cs b/ModTek/Features/Logging/Filters.cs index dce6f32d..046692f3 100644 --- a/ModTek/Features/Logging/Filters.cs +++ b/ModTek/Features/Logging/Filters.cs @@ -1,62 +1,575 @@ -using System.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using HBS.Logging; namespace ModTek.Features.Logging; -internal class Filters +internal static class Filters { - private readonly Filter[] _includeFilters; - private readonly Filter[] _excludeFilters; - - internal Filters(AppenderSettings settings) + private static readonly string Achievements = string.Intern("Achievements"); + private static readonly string Analytics = string.Intern("Analytics"); + private static readonly string AudioEvents = string.Intern("AudioEvents"); + private static readonly string BattleTechServices = string.Intern("BattleTech.Services"); + private static readonly string CombatLogHit = string.Intern("CombatLog.Hit"); + private static readonly string CombatLogInitialization = string.Intern("CombatLog.Initialization"); + private static readonly string CustomComponents = string.Intern("CustomComponents"); + private static readonly string CustomComponentsUnitType = string.Intern("CustomComponents.UnitType"); + private static readonly string DataAssetBundleManager = string.Intern("Data.AssetBundleManager"); + private static readonly string DataDataManager = string.Intern("Data.DataManager"); + private static readonly string DataLoader = string.Intern("DataLoader"); + private static readonly string DebugBridge = string.Intern("DebugBridge"); + private static readonly string GameInfo = string.Intern("GameInfo"); + private static readonly string HarmonyX = string.Intern("HarmonyX"); + private static readonly string LewdableTanks = string.Intern("LewdableTanks"); + private static readonly string LoginManager = string.Intern("LoginManager"); + private static readonly string MapExport = string.Intern("MapExport"); + private static readonly string MechEngineer = string.Intern("MechEngineer"); + private static readonly string MechLab = string.Intern("MechLab"); + private static readonly string NetworkClient = string.Intern("Network.Client"); + private static readonly string NetworkRandomCallstacks = string.Intern("NetworkRandomCallstacks"); + private static readonly string NetworkRandomValues = string.Intern("NetworkRandomValues"); + private static readonly string PilotDef = string.Intern("PilotDef"); + private static readonly string SaveCoreSaveSystem = string.Intern("Save.Core.SaveSystem"); + private static readonly string UI = string.Intern("UI"); + private static readonly string Unity = string.Intern("Unity"); + private static readonly string UserSettings = string.Intern("UserSettings"); + private static unsafe bool FastStartsWith(string instance, string str) + { + return false; + } + internal static bool HardcodedFilter(ref MTLoggerMessageDto messageDto) { - if (settings.Includes != null) + var loggerName = messageDto.LoggerName; + var logLevel = messageDto.LogLevel; + var message = messageDto.Message; + if (ReferenceEquals(loggerName, Achievements)) { - _includeFilters = settings.Includes.Select(fs => new Filter(fs)).ToArray(); + if (logLevel == LogLevel.Log) + { + return false; + } } - if (settings.Excludes != null) + if (ReferenceEquals(loggerName, Analytics)) { - _excludeFilters = settings.Excludes.Select(fs => new Filter(fs)).ToArray(); + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("Analytics Event requested with invalid IP")) + { + return false; + } + if (message.StartsWith("Request next called but no servers have been found")) + { + return false; + } + if (message.StartsWith("Request next called but reporting is disabled")) + { + return false; + } + } } - - // support old prefixes style - if (settings.PrefixesToIgnore != null) + if (ReferenceEquals(loggerName, AudioEvents)) { - var legacyFilters = LinePrefixToFilterTransformer.CreateFilters(settings.PrefixesToIgnore).ToArray(); - _excludeFilters = _excludeFilters == null ? legacyFilters : [.._excludeFilters, ..legacyFilters]; + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("Audio Engine")) + { + return false; + } + if (message.StartsWith("OnApplicationFocus")) + { + return false; + } + } } - } - - internal bool IsIncluded(ref MTLoggerMessageDto messageDto) - { - if (_includeFilters != null) + if (ReferenceEquals(loggerName, BattleTechServices)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("[BattleTechParadoxAPI]")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, CombatLogHit)) { - var found = false; - foreach (var filter in _includeFilters) + if (logLevel == LogLevel.Log) { - if (filter.IsMatch(ref messageDto)) + if (message.StartsWith("???????? DIRECTION:")) { - found = true; - break; + return false; } } - - if (!found) + } + if (ReferenceEquals(loggerName, CombatLogInitialization)) + { + if (logLevel == LogLevel.Error) + { + if (message.StartsWith("Error instantiating VFX")) + { + return false; + } + } + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("Turret")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, CustomComponents)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("[CC]-- CustomComponents.AutoLinked")) + { + return false; + } + if (message.StartsWith("[CC]-- CustomComponents.Flags")) + { + return false; + } + if (message.StartsWith("[CC]Mech validation for NULL return")) + { + return false; + } + } + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("[CC]SimpleCustom")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, CustomComponentsUnitType)) + { + if (logLevel == LogLevel.Debug) { return false; } } - - if (_excludeFilters != null) + if (ReferenceEquals(loggerName, DataAssetBundleManager)) { - foreach (var filter in _excludeFilters) + if (logLevel == LogLevel.Log) { - if (filter.IsMatch(ref messageDto)) + if (message.StartsWith("Trying to load AssetBundle:")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, DataDataManager)) + { + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("LoadRequest for")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, DataLoader)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("Loading:")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, DebugBridge)) + { + return false; + } + if (ReferenceEquals(loggerName, GameInfo)) + { + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("DEVELOPMENT FLAG NOT SET")) + { + return false; + } + if (message.StartsWith("ProductName: BATTLETECH")) + { + return false; + } + if (message.StartsWith("RELEASE FLAG SET")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, HarmonyX)) + { + if (logLevel == LogLevel.Log) + { + return false; + } + if (logLevel == (LogLevel)200) + { + return false; + } + } + if (ReferenceEquals(loggerName, LewdableTanks)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("Fixing cost of")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, LoginManager)) + { + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("Successfully authenticated with OPS. Moving onto ComStar connection proper.")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, MapExport)) + { + if (logLevel == LogLevel.Error) + { + if (message.StartsWith("Out of bounds")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, MechEngineer)) + { + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("Auto fixing chassisDef")) + { + return false; + } + if (message.StartsWith("settings loaded")) + { + return false; + } + } + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("Unsupported weapon category for 666")) + { + return false; + } + if (message.StartsWith("Unsupported weapon category for 667")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, MechLab)) + { + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("GetWeaponPrefabName failed to find a prefab name for unit")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, NetworkClient)) + { + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("Connection")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, NetworkRandomCallstacks)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("Seed")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, NetworkRandomValues)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("Seed")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, PilotDef)) + { + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("PilotDef already did Init From Save!")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, SaveCoreSaveSystem)) + { + if (logLevel == LogLevel.Debug) + { + return false; + } + } + if (ReferenceEquals(loggerName, UI)) + { + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("Singleton UIManagerFader")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, Unity)) + { + if (logLevel == LogLevel.Error) + { + if (message.StartsWith("================== ERROR! Found missing transforms")) + { + return false; + } + if (message.StartsWith("Bones do not match bindpose.")) + { + return false; + } + if (message.StartsWith("Desired shader compiler platform")) + { + return false; + } + if (message.StartsWith("Generating SIM GAME UID while still loading!")) + { + return false; + } + if (message.StartsWith("Material doesn't have a color property")) + { + return false; + } + if (message.StartsWith("RenderTexture.Create failed: format unsupported for random writes")) + { + return false; + } + } + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("Look rotation viewing vector is zero")) + { + return false; + } + } + if (logLevel == LogLevel.Warning) + { + if (message.StartsWith("BoxColliders does not support negative scale or size")) + { + return false; + } + if (message.StartsWith("Could not retrieve member")) + { + return false; + } + if (message.StartsWith("ERROR! Couldn't auto-setup")) + { + return false; + } + if (message.StartsWith("HBS Tooltip on UI Element")) + { + return false; + } + if (message.StartsWith("No DefaultCombatLeaderCastDefId specified for faction [Player1sMercUnit]")) + { + return false; + } + if (message.StartsWith("No DefaultCombatLeaderCastDefId specified for faction [Player2sMercUnit]")) + { + return false; + } + if (message.StartsWith("Parent of RectTransform is being set with parent property")) + { + return false; + } + if (message.StartsWith("Rejecting unit")) + { + return false; + } + if (message.StartsWith("The referenced script")) + { + return false; + } + } + } + if (ReferenceEquals(loggerName, UserSettings)) + { + if (logLevel == LogLevel.Debug) + { + if (message.StartsWith("Using existing cloud settings from save manager")) + { + return false; + } + } + if (logLevel == LogLevel.Log) + { + if (message.StartsWith("[LOG] User settings saved")) { return false; } } } - return true; } + + internal delegate bool FilterDelegate(ref MTLoggerMessageDto messageDto); + internal static FilterDelegate Compile(AppenderSettings settings) + { + var messageDto = Expression.Parameter(typeof(MTLoggerMessageDto).MakeByRefType(), "messageDto"); + + Expression filter = null; + + if (settings.Includes is { Length: > 0 }) + { + var subFilter = AssembleFilterExpression(messageDto, settings.Includes[0]); + for (var i = 1; i < settings.Includes.Length; i++) + { + subFilter = Expression.Or(subFilter, AssembleFilterExpression(messageDto, settings.Includes[i])); + } + filter = subFilter; + } + + if (settings.Excludes is { Length: > 0 }) + { + var subFilter = AssembleFilterExpression(messageDto, settings.Excludes[0]); + for (var i = 1; i < settings.Excludes.Length; i++) + { + subFilter = Expression.Or(subFilter, AssembleFilterExpression(messageDto, settings.Excludes[i])); + } + subFilter = Expression.Not(subFilter); + + filter = filter == null ? subFilter : Expression.And(filter, subFilter); + } + + if (settings.PrefixesToIgnore is { Length: > 0 }) + { + var legacyFilters = LinePrefixToFilterTransformer.CreateFilters(settings.PrefixesToIgnore).ToArray(); + var subFilter = AssembleFilterExpression(messageDto, legacyFilters[0]); + for (var i = 1; i < legacyFilters.Length; i++) + { + subFilter = Expression.Or(subFilter, AssembleFilterExpression(messageDto, legacyFilters[i])); + } + subFilter = Expression.Not(subFilter); + + filter = filter == null ? subFilter : Expression.And(filter, subFilter); + } + + if (filter == null) + { + filter = Expression.Constant(true); + } + + var lambda = Expression.Lambda(filter, messageDto); + File.AppendAllText("Mods/.modtek/exptest.txt",lambda + "\n"); + var compiled = lambda.Compile(); + File.AppendAllText("Mods/.modtek/exptest.txt",compiled.Method + "\n"); + File.AppendAllText("Mods/.modtek/exptest.txt",compiled.Method.Module + "\n"); + File.AppendAllText("Mods/.modtek/exptest.txt","\n"); + return compiled; + } + + static Filters() + { + File.WriteAllText("Mods/.modtek/exptest.txt",""); + } + + private static Expression AssembleFilterExpression(Expression messageDto, FilterSettings settings) + { + Expression filter = null; + + if (settings.LoggerNames is { Length: > 0 }) + { + // Intern allows us to use ReferenceEquals a.k.a == + // since logger names are already interned by LogImpl + var loggerNames = settings.LoggerNames.Select(string.Intern).ToArray(); + + var loggerName = Expression.MakeMemberAccess( + messageDto, + AccessTools.Field(typeof(MTLoggerMessageDto), nameof(MTLoggerMessageDto.LoggerName)) + ); + var subFilter = AssembleEqualsFilterExpression(loggerName, loggerNames, Expression.ReferenceEqual); + filter = subFilter; + } + + if (settings.LogLevels is { Length: > 0 }) + { + var logLevel = Expression.MakeMemberAccess( + messageDto, + AccessTools.Field(typeof(MTLoggerMessageDto), nameof(MTLoggerMessageDto.LogLevel)) + ); + var subFilter = AssembleEqualsFilterExpression(logLevel, settings.LogLevels, Expression.Equal); + filter = filter == null ? subFilter : Expression.And(filter, subFilter); + } + + if (settings.MessagePrefixes is { Length: > 0 }) + { + try + { + var message = Expression.MakeMemberAccess( + messageDto, + AccessTools.Field(typeof(MTLoggerMessageDto), nameof(MTLoggerMessageDto.Message)) + ); + + // var trie = Trie.Create(settings.MessagePrefixes); + // var messagePrefixesRegex2 = trie.CompileRegex(); + // var messagePrefixesRegex = Expression.Constant(messagePrefixesRegex2); + // var isMatch = SymbolExtensions.GetMethodInfo(() => messagePrefixesRegex2.IsMatch("")); + // var subFilter = Expression.Call(messagePrefixesRegex, isMatch, message); + + var prefixes = settings.MessagePrefixes.OrderBy(x => x).Distinct().ToArray(); + var startsWith = AccessTools.Method(typeof(string), "StartsWith", [typeof(string)]); + var subFilter = AssembleEqualsFilterExpression(message, prefixes, + (input, str) => Expression.Call(input, startsWith, str)); + + filter = filter == null ? subFilter : Expression.And(filter, subFilter); + } + catch (Exception e) + { + throw new Exception($"Issue processing {nameof(FilterSettings)}.{nameof(FilterSettings.MessagePrefixes)}", e); + } + } + + if (filter == null) + { + filter = Expression.Constant(true); + } + + return filter; + } + + private static Expression AssembleEqualsFilterExpression( + Expression input, + T[] array, + Func eqExpressionFunc) + { + var expression = eqExpressionFunc(input, Expression.Constant(array[0])); + for (var i = 1; i < array.Length; i++) + { + var eqExpression = eqExpressionFunc(input, Expression.Constant(array[i])); + expression = Expression.Or(expression, eqExpression); + } + return expression; + } } \ No newline at end of file diff --git a/ModTek/Features/Logging/LinePrefixToFilterTransformer.cs b/ModTek/Features/Logging/LinePrefixToFilterTransformer.cs index db36f8cd..1d24e0d0 100644 --- a/ModTek/Features/Logging/LinePrefixToFilterTransformer.cs +++ b/ModTek/Features/Logging/LinePrefixToFilterTransformer.cs @@ -9,7 +9,7 @@ namespace ModTek.Features.Logging; internal static class LinePrefixToFilterTransformer { - internal static List CreateFilters(string[] prefixes) + internal static List CreateFilters(string[] prefixes) { var all = prefixes .Select(CreateFilterSettingsFromLinePrefix) @@ -18,7 +18,7 @@ internal static List CreateFilters(string[] prefixes) .ThenBy(x => x.MessagePrefixes?[0]) .ToList(); - var filters = new List(); + var filters = new List(); FilterSettings last = null; foreach (var current in all) { @@ -33,12 +33,12 @@ internal static List CreateFilters(string[] prefixes) continue; } - filters.Add(new Filter(last)); + filters.Add(last); last = current; } if (last != null) { - filters.Add(new Filter(last)); + filters.Add(last); } return filters; } diff --git a/ModTek/Features/Logging/Trie.cs b/ModTek/Features/Logging/Trie.cs index 4de5c781..1e510b3a 100644 --- a/ModTek/Features/Logging/Trie.cs +++ b/ModTek/Features/Logging/Trie.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Text; using System.Text.RegularExpressions; @@ -54,6 +55,53 @@ internal Regex CompileRegex() return new Regex(sb.ToString(), RegexOptions.Compiled); } + /* + var length = message.Length; + const string sw1 = "This "; + const int sw1Length = 6; + sw1.StartsWith() + if (length >= 17 && SequenceStartsWith(message, 0, sw1Length, sw1)) + { + const string sw2 = "is Test."; + if (SequenceStartsWith(message, sw1Length, sw2)) + { + return true; + } + + const string sw3 = "was a Test."; + if (length >= 20 && SequenceStartsWith(message, sw1Length, sw3)) + { + switch (message[19]) + { + case '!': + case '.': + return true; + } + } + } + return false; + */ +/* + internal Func CompileLambda() + { + var inputParameter = Expression.Parameter(typeof(string), "text"); + + var traverser = new Traverser + { + enteredNode = node => sb.Append(node.prefixPart), + enteringFirstSibling = node => sb.Append("(?:"), + enteringNextSibling = node => sb.Append("|"), + exitedLastSibling = node => sb.Append(")") + }; + Traverse(traverser); + Expression.Variable(); + var constant = Expression.Constant(10); + Expression.GreaterThan(); + Expression.Call() + + return Expression.Lambda>(lastExpression, inputParameter).Compile(); + }*/ + private class Traverser { internal Action enteredNode; diff --git a/ModTek/Util/Stopwatch/MTStopwatchWithCallback.cs b/ModTek/Util/Stopwatch/MTStopwatchWithCallback.cs index a9663f72..0769c18d 100644 --- a/ModTek/Util/Stopwatch/MTStopwatchWithCallback.cs +++ b/ModTek/Util/Stopwatch/MTStopwatchWithCallback.cs @@ -22,6 +22,6 @@ protected override void AddMeasurement(long elapsedTicks, long delta) _callback.Invoke(new MTStopwatchStats(this, count, ticks)); } } - private const long CallbackEveryMeasurement = 1 << 14; // every 16k, FastModulo requires base 2 + private const long CallbackEveryMeasurement = 1 << 10; // every 16k, FastModulo requires base 2 private const long CallbackFastModuloMask = CallbackEveryMeasurement - 1; } \ No newline at end of file