using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ErrorAnalyzer")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace ErrorAnalyzer;
[BepInPlugin("aaa.dsp.plugin.ErrorAnalyzer", "ErrorAnalyzer", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "aaa.dsp.plugin.ErrorAnalyzer";
public const string NAME = "ErrorAnalyzer";
public const string VERSION = "1.1.0";
public static ManualLogSource Log;
public static bool isRegisitered;
public static string errorString;
public static string errorStackTrace;
private static Harmony harmony;
public void Awake()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
harmony = new Harmony("aaa.dsp.plugin.ErrorAnalyzer");
if (!Chainloader.PluginInfos.TryGetValue("dsp.nebula-multiplayer", out var value))
{
try
{
harmony.PatchAll(typeof(UIFatalErrorTip_Patch));
Application.logMessageReceived += new LogCallback(HandleLog);
isRegisitered = true;
}
catch (Exception ex)
{
Log.LogError((object)"Error when patching UIFatalErrorTip_Patch");
Log.LogError((object)ex);
}
}
if (!Chainloader.PluginInfos.TryGetValue("NebulaCompatibilityAssist", out value))
{
try
{
harmony.PatchAll(typeof(StacktraceParser));
}
catch (Exception ex2)
{
Log.LogError((object)"Error when patching StacktraceParser");
Log.LogError((object)ex2);
}
}
}
public void OnDestroy()
{
harmony.UnpatchSelf();
harmony = null;
}
public static void HandleLog(string logString, string stackTrace, LogType type)
{
if (string.IsNullOrEmpty(errorString) && logString.IndexOf("Exception") > 0)
{
errorString = logString;
errorStackTrace = stackTrace;
Log.LogDebug((object)"Exception Record");
}
}
}
internal class StacktraceParser
{
private static bool IsChecked;
private static Dictionary<string, List<MethodBase>> patchMap;
[HarmonyPostfix]
[HarmonyPatch(typeof(UIFatalErrorTip), "_OnClose")]
public static void OnClose_Postfix()
{
IsChecked = false;
patchMap = null;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIFatalErrorTip), "_OnOpen")]
public static void OnOpen_Postfix(UIFatalErrorTip __instance)
{
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
if (IsChecked)
{
return;
}
if (patchMap == null)
{
patchMap = new Dictionary<string, List<MethodBase>>();
foreach (MethodBase allPatchedMethod in PatchProcessor.GetAllPatchedMethods())
{
string fullName = allPatchedMethod.DeclaringType.FullName;
if (!patchMap.TryGetValue(fullName, out var value))
{
value = new List<MethodBase>();
patchMap[fullName] = value;
}
value.Add(allPatchedMethod);
}
Plugin.Log.LogDebug((object)("Patched type: " + patchMap.Count));
}
List<MethodBase> modifiedMethods = new List<MethodBase>();
ParseStackTraceLines(__instance.errorLogText.text, delegate(string typeName, string methodName)
{
if (patchMap.TryGetValue(typeName, out var value2))
{
foreach (MethodBase item in value2)
{
if (item.Name == methodName)
{
modifiedMethods.Add(item);
}
}
}
});
Text errorLogText = __instance.errorLogText;
errorLogText.text += GetResultString(modifiedMethods);
__instance.rectTrans.sizeDelta = new Vector2(__instance.rectTrans.sizeDelta.x, __instance.errorLogText.preferredHeight + 45f);
((Graphic)__instance.errorLogText).rectTransform.sizeDelta = new Vector2(((Graphic)__instance.errorLogText).rectTransform.sizeDelta.x, __instance.errorLogText.preferredHeight + 2f);
IsChecked = true;
}
private static void ParseStackTraceLines(string source, Action<string, string> validate)
{
string[] array = source.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string text in array)
{
int num = text.IndexOf('(');
if (num != -1)
{
int num2 = text.LastIndexOf('.', num);
if (num2 != -1 && num - num2 - 2 > 0)
{
string arg = ((!text.StartsWith(" at ")) ? text.Substring(0, num2) : text.Substring(5, num2 - 5));
string arg2 = text.Substring(num2 + 1, num - num2 - 2);
validate(arg, arg2);
}
}
}
}
private static string GetResultString(List<MethodBase> modifiedMethods)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (MethodBase modifiedMethod in modifiedMethods)
{
Patches patchInfo = PatchProcessor.GetPatchInfo(modifiedMethod);
PatchesToString(stringBuilder, modifiedMethod.Name, "Prefix", patchInfo.Prefixes);
PatchesToString(stringBuilder, modifiedMethod.Name, "Postfix", patchInfo.Postfixes);
PatchesToString(stringBuilder, modifiedMethod.Name, "Transpiler", patchInfo.Transpilers);
Plugin.Log.LogDebug((object)(modifiedMethod.Name + " owners:" + patchInfo.Owners.Count));
}
if (stringBuilder.Length > 0)
{
stringBuilder.Insert(0, "\n== Mod patches on the stack ==\n");
}
return stringBuilder.ToString();
}
private static void PatchesToString(StringBuilder sb, string name, string prefix, ReadOnlyCollection<Patch> patches)
{
foreach (Patch patch in patches)
{
if (!IsWhitelist(name, patch))
{
sb.Append(name).Append("(").Append(prefix)
.Append("): ");
if (prefix != "Transpiler")
{
sb.AppendLine(GeneralExtensions.FullDescription((MethodBase)patch.PatchMethod));
}
else
{
sb.AppendLine(GeneralExtensions.FullDescription((MethodBase)patch.PatchMethod).Replace("System.Collections.Generic.IEnumerable<HarmonyLib.CodeInstruction>", "var").Replace("System.Reflection.Emit.ILGenerator", "var"));
}
}
}
}
private static bool IsWhitelist(string name, Patch patch)
{
return false;
}
}
[HarmonyPatch(typeof(UIFatalErrorTip))]
internal class UIFatalErrorTip_Patch
{
private static GameObject button1;
[HarmonyPostfix]
[HarmonyPatch("_OnRegEvent")]
private static void _OnRegEvent_Postfix()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
if (!Plugin.isRegisitered)
{
return;
}
Plugin.isRegisitered = false;
try
{
Application.logMessageReceived -= new LogCallback(Plugin.HandleLog);
if (!string.IsNullOrEmpty(Plugin.errorString))
{
UIFatalErrorTip.instance.ShowError(Plugin.errorString, Plugin.errorStackTrace);
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)ex);
}
}
[HarmonyPostfix]
[HarmonyPatch("_OnOpen")]
private static void _OnOpen_Postfix()
{
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)button1 == (Object)null)
{
GameObject val = GameObject.Find("UI Root/Overlay Canvas/Fatal Error/errored-panel/");
((Component)val.transform.Find("tip-text-0")).GetComponent<Text>().text = Title();
Object.Destroy((Object)(object)((Component)val.transform.Find("tip-text-0")).GetComponent<Localizer>());
((Component)val.transform.Find("tip-text-1")).GetComponent<Text>().text = Title();
Object.Destroy((Object)(object)((Component)val.transform.Find("tip-text-1")).GetComponent<Localizer>());
button1 = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Dyson Sphere Editor/Dyson Editor Control Panel/hierarchy/layers/blueprint-group/blueprint-2/copy-button");
button1 = Object.Instantiate<GameObject>(button1, val.transform);
((Object)button1).name = "Copy button";
button1.transform.localPosition = val.transform.Find("icon").localPosition + new Vector3(30f, -35f, 0f);
((Graphic)button1.GetComponent<Image>()).color = new Color(0.6f, 0.1f, 0.1f, 0.6f);
button1.GetComponent<UIButton>().BindOnClickSafe((Action<int>)OnClick1);
ref TipSettings tips = ref button1.GetComponent<UIButton>().tips;
tips.tipTitle = "Copy Error";
tips.tipText = "Copy the message to clipboard and close error.";
tips.corner = 1;
}
}
catch (Exception arg)
{
Plugin.Log.LogWarning((object)$"UIFatalErrorTip button did not patch! {arg}");
}
}
private static string Title()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("An error has occurred! Game version ");
Version gameVersion = GameConfig.gameVersion;
stringBuilder.Append(((object)(Version)(ref gameVersion)).ToString());
stringBuilder.Append('.');
stringBuilder.Append(GameConfig.gameVersion.Build);
stringBuilder.AppendLine();
stringBuilder.Append(Chainloader.PluginInfos.Values.Count + " Mods used: ");
foreach (PluginInfo value in Chainloader.PluginInfos.Values)
{
stringBuilder.Append('[');
stringBuilder.Append(value.Metadata.Name);
stringBuilder.Append(value.Metadata.Version);
stringBuilder.Append("] ");
}
return stringBuilder.ToString();
}
private static void OnClick1(int id)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("```ini");
stringBuilder.AppendLine(Title());
string[] array = UIFatalErrorTip.instance.errorLogText.text.Split('\n', '\r');
foreach (string text in array)
{
if (!string.IsNullOrEmpty(text))
{
int num = text.LastIndexOf(" <", StringComparison.Ordinal);
int num2 = text.LastIndexOf(">:", StringComparison.Ordinal);
if (num != -1 && num2 > num)
{
stringBuilder.AppendLine(text.Remove(num, num2 - num + 2));
}
else
{
stringBuilder.AppendLine(text);
}
}
}
stringBuilder.Replace(" (at", ";(");
stringBuilder.Replace(" inIL_", " ;IL_");
stringBuilder.AppendLine("```");
GUIUtility.systemCopyBuffer = stringBuilder.ToString();
UIFatalErrorTip.ClearError();
Object.Destroy((Object)(object)button1);
button1 = null;
}
}