diff --git a/project/Aki.Custom/Models/BsgLoggingResponse.cs b/project/Aki.Custom/Models/BsgLoggingResponse.cs new file mode 100644 index 0000000..5c3fab9 --- /dev/null +++ b/project/Aki.Custom/Models/BsgLoggingResponse.cs @@ -0,0 +1,5 @@ +public struct LoggingLevelResponse +{ + public int verbosity { get; set; } + public bool sendToServer {get; set; } +} \ No newline at end of file diff --git a/project/Aki.Debugging/Aki.Debugging.csproj b/project/Aki.Debugging/Aki.Debugging.csproj index ae60ee6..e6b446e 100644 --- a/project/Aki.Debugging/Aki.Debugging.csproj +++ b/project/Aki.Debugging/Aki.Debugging.csproj @@ -24,6 +24,7 @@ + diff --git a/project/Aki.Debugging/AkiDebuggingPlugin.cs b/project/Aki.Debugging/AkiDebuggingPlugin.cs index f4c9876..1258d7b 100644 --- a/project/Aki.Debugging/AkiDebuggingPlugin.cs +++ b/project/Aki.Debugging/AkiDebuggingPlugin.cs @@ -1,5 +1,7 @@ using System; using Aki.Common; +using Aki.Common.Http; +using Aki.Common.Utils; using Aki.Debugging.Patches; using BepInEx; @@ -8,6 +10,8 @@ namespace Aki.Debugging [BepInPlugin("com.spt-aki.debugging", "AKI.Debugging", AkiPluginInfo.PLUGIN_VERSION)] public class AkiDebuggingPlugin : BaseUnityPlugin { + public static LoggingLevelResponse logLevel; + public void Awake() { Logger.LogInfo("Loading: Aki.Debugging"); @@ -15,6 +19,7 @@ namespace Aki.Debugging try { new EndRaidDebug().Enable(); + new LoggerClassLogPatch().Enable(); // new CoordinatesPatch().Enable(); // new StaticLootDumper().Enable(); @@ -32,5 +37,11 @@ namespace Aki.Debugging Logger.LogInfo("Completed: Aki.Debugging"); } + + public void Start() + { + var loggingJson = RequestHandler.GetJson("/singleplayer/enableBSGlogging"); + logLevel = Json.Deserialize(loggingJson); + } } } diff --git a/project/Aki.Debugging/Patches/LoggerClassPatch.cs b/project/Aki.Debugging/Patches/LoggerClassPatch.cs new file mode 100644 index 0000000..6ec94c8 --- /dev/null +++ b/project/Aki.Debugging/Patches/LoggerClassPatch.cs @@ -0,0 +1,54 @@ +using System.Reflection; +using System.Text.RegularExpressions; +using Aki.Common.Utils; +using Aki.Reflection.Patching; +using Aki.Reflection.Utils; +using HarmonyLib; +using NLog; + +namespace Aki.Debugging.Patches +{ + public class LoggerClassLogPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.GetDeclaredMethods(typeof(LoggerClass)) + .SingleCustom(m => m.Name == nameof(LoggerClass.Log) && m.GetParameters().Length == 4); + } + + [PatchPostfix] + private static void PatchPostfix(string nlogFormat, string unityFormat, LogLevel logLevel, object[] args) + { + var bsgLevel = LogLevel.FromOrdinal(logLevel.Ordinal); + var sptLevel = LogLevel.FromOrdinal(AkiDebuggingPlugin.logLevel.verbosity); + + // See Nlog docs for information on ordinal levels + // Ordinal works from low to high 0 - trace, 1 - debug, 3 - info ... + if (bsgLevel >= sptLevel) + { + // We want to remove any character thats not a single digit inside of {} + // This prevents string builder exceptions. + nlogFormat = Regex.Replace(nlogFormat, @"\{[^{}]*[^\d{}][^{}]*\}", ""); + nlogFormat = string.Format(nlogFormat, args); + + Logger.LogDebug($"output Nlog: {logLevel} : {nlogFormat}"); + + if (AkiDebuggingPlugin.logLevel.sendToServer) + { + ServerLog.Info("EFT Logging:", $"{logLevel} : {nlogFormat}"); + } + } + + // I've opted to leave this disabled for now, it doesn't add much in + // terms of value, its mostly the same stuff as the nlogFormat + // Deciced to keep it here incase we decide we want it later. + // After a 5 minute factory run at full verbosity, i ended up with a 20K + // line long player.log file. + + //unityFormat = Regex.Replace(unityFormat, @"\{[^{}]*[^\d{}][^{}]*\}", ""); + //unityFormat = string.Format(unityFormat, args); + //Logger.LogDebug($"Verbosity: {logLevel}"); + //Logger.LogDebug($"output unity: {unityFormat}"); + } + } +} \ No newline at end of file