Decompiled source of TABSCrashLog v1.0.0

TabsCrashLog.dll

Decompiled 4 days ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TabsCrashLog
{
	internal static class CrashLogWriter
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static LogCallback <0>__OnLogMessage;

			public static UnhandledExceptionEventHandler <1>__OnUnhandledException;
		}

		private const string Divider = "──────────────────────────────────────────────";

		private const string FatalDivider = "══════════════════════════════════════════════";

		private static readonly object Lock = new object();

		private static readonly Regex StackFrameRegex = new Regex("^\\s*at\\s+(.+?)(?:\\s+\\[|$)", RegexOptions.Compiled);

		private static string _path;

		private static bool _initialized;

		private static bool _headerWritten;

		private static string _lastReason;

		internal static string LogPath => _path;

		internal static void Initialize()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if (!_initialized)
			{
				_initialized = true;
				_path = ResolveLogPath();
				ResetLogFile();
				object obj = <>O.<0>__OnLogMessage;
				if (obj == null)
				{
					LogCallback val = OnLogMessage;
					<>O.<0>__OnLogMessage = val;
					obj = (object)val;
				}
				Application.logMessageReceived += (LogCallback)obj;
				AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
			}
		}

		internal static void Shutdown()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__OnLogMessage;
			if (obj == null)
			{
				LogCallback val = OnLogMessage;
				<>O.<0>__OnLogMessage = val;
				obj = (object)val;
			}
			Application.logMessageReceived -= (LogCallback)obj;
			AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException;
		}

		private static string ResolveLogPath()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(Application.dataPath);
				if (!string.IsNullOrEmpty(directoryName))
				{
					return Path.Combine(directoryName, "crash.log");
				}
			}
			catch
			{
			}
			return Path.Combine(Paths.BepInExRootPath, "crash.log");
		}

		private static void ResetLogFile()
		{
			lock (Lock)
			{
				try
				{
					File.WriteAllText(_path, $"=== TABS Crash Log — {DateTime.Now:yyyy-MM-dd HH:mm:ss} ===\n\n");
					_headerWritten = true;
				}
				catch
				{
					_headerWritten = false;
				}
			}
		}

		private unsafe static void OnLogMessage(string message, string stackTrace, LogType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if ((int)type != 0 && (int)type != 4 && (int)type != 1)
			{
				return;
			}
			string arg = (((int)type == 4) ? "EXCEPTION" : ((object)(*(LogType*)(&type))/*cast due to .constrained prefix*/).ToString().ToUpperInvariant());
			string text = message?.Trim() ?? string.Empty;
			if (string.IsNullOrEmpty(text))
			{
				text = "(no message)";
			}
			if (!(text == _lastReason) || !string.IsNullOrWhiteSpace(stackTrace))
			{
				_lastReason = text;
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("──────────────────────────────────────────────");
				stringBuilder.AppendLine($"[{DateTime.Now:HH:mm:ss}] {arg}");
				stringBuilder.AppendLine("REASON : " + text);
				string text2 = ExtractSource(stackTrace);
				if (!string.IsNullOrEmpty(text2))
				{
					stringBuilder.AppendLine("SOURCE : " + text2);
				}
				AppendStackTrace(stringBuilder, stackTrace);
				stringBuilder.AppendLine("──────────────────────────────────────────────");
				Write(stringBuilder.ToString());
			}
		}

		private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("══════════════════════════════════════════════");
			stringBuilder.AppendLine($"[{DateTime.Now:HH:mm:ss}] *** FATAL UNHANDLED EXCEPTION ***");
			if (e.ExceptionObject is Exception ex)
			{
				string text = (string.IsNullOrWhiteSpace(ex.Message) ? ex.GetType().Name : (ex.GetType().Name + " — " + ex.Message));
				stringBuilder.AppendLine("REASON : " + text);
				if (!string.IsNullOrEmpty(ex.Source))
				{
					stringBuilder.AppendLine("SOURCE : " + ex.Source);
				}
				stringBuilder.AppendLine();
				stringBuilder.AppendLine(ex.ToString());
			}
			else
			{
				stringBuilder.AppendLine($"REASON : {e.ExceptionObject}");
			}
			stringBuilder.AppendLine("══════════════════════════════════════════════");
			Write(stringBuilder.ToString());
		}

		private static string ExtractSource(string stackTrace)
		{
			if (string.IsNullOrWhiteSpace(stackTrace))
			{
				return null;
			}
			string[] array = stackTrace.Split(new char[1] { '\n' });
			foreach (string input in array)
			{
				Match match = StackFrameRegex.Match(input);
				if (match.Success)
				{
					return match.Groups[1].Value.Trim();
				}
			}
			return null;
		}

		private static void AppendStackTrace(StringBuilder sb, string stackTrace)
		{
			if (string.IsNullOrWhiteSpace(stackTrace))
			{
				return;
			}
			sb.AppendLine();
			string[] array = stackTrace.Split(new char[1] { '\n' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].TrimEnd(new char[1] { '\r' });
				if (!string.IsNullOrWhiteSpace(text))
				{
					sb.AppendLine("  " + text);
				}
			}
		}

		private static void Write(string block)
		{
			lock (Lock)
			{
				try
				{
					if (!_headerWritten)
					{
						File.AppendAllText(_path, $"=== TABS Crash Log — {DateTime.Now:yyyy-MM-dd HH:mm:ss} ===\n\n");
						_headerWritten = true;
					}
					File.AppendAllText(_path, block);
				}
				catch
				{
				}
			}
		}
	}
	internal static class ModInfo
	{
		public const string Author = "Pretz";

		public const string PluginGuid = "pretz.tabscrashlog";

		public const string PluginName = "TABS Crash Log";

		public const string Version = "1.0.1";
	}
	[BepInPlugin("pretz.tabscrashlog", "TABS Crash Log", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			CrashLogWriter.Initialize();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Crash log: " + CrashLogWriter.LogPath));
		}

		private void OnDestroy()
		{
			CrashLogWriter.Shutdown();
		}
	}
}