Decompiled source of The Eye v2.1.1

plugins/WubarrksEye/WubarrksEye.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using WubarrksEye.Core;
using WubarrksEye.Core.Commands;
using WubarrksEye.Core.Dumpers;
using WubarrksEye.Core.Patches;
using WubarrksEye.Core.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
public static class DeepReflectionWalker
{
	private sealed class ReferenceEqualityComparer : IEqualityComparer<object>
	{
		public static readonly ReferenceEqualityComparer Instance = new ReferenceEqualityComparer();

		public new bool Equals(object x, object y)
		{
			return x == y;
		}

		public int GetHashCode(object obj)
		{
			return RuntimeHelpers.GetHashCode(obj);
		}
	}

	private const int MAX_DEPTH = 32;

	private const int MAX_ITEMS = 500000;

	private static readonly HashSet<object> _visited = new HashSet<object>(ReferenceEqualityComparer.Instance);

	private static int _count;

	private static readonly string[] ForbiddenTypePrefixes = new string[35]
	{
		"PlayFab", "Steamworks", "UnityEngine.Networking", "UnityEngine.ResourceRequest", "UnityEngine.AsyncOperation", "System.Runtime.CompilerServices", "System.Threading", "System.Net", "System.IO", "System.Reflection.Emit",
		"System.Security", "System.Diagnostics", "System.Runtime.Remoting", "System.Runtime.InteropServices", "System.Runtime.Serialization", "System.Runtime.ExceptionServices", "System.Runtime.ConstrainedExecution", "System.Runtime.Versioning", "System.Runtime.Loader", "System.Runtime.GCSettings",
		"System.RuntimeType", "System.RuntimeTypeHandle", "System.RuntimeFieldHandle", "System.RuntimeMethodHandle", "System.RuntimeArgumentHandle", "System.RuntimeMethodInfoStub", "System.RuntimePropertyInfoStub", "System.RuntimeEventInfoStub", "System.RuntimeConstructorInfoStub", "System.RuntimeType+",
		"System.Runtime.CompilerServices.AsyncTaskMethodBuilder", "<>", "c__DisplayClass", "d__", "PrivateImplementationDetails"
	};

	public static void Walk(object root, Action<string, object> onField)
	{
		_visited.Clear();
		_count = 0;
		WalkInternal(root, "root", 0, onField);
	}

	private static void WalkInternal(object obj, string path, int depth, Action<string, object> onField)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		if (obj == null || depth > 32 || _count++ > 500000)
		{
			return;
		}
		Type type = obj.GetType();
		if (IsForbidden(type))
		{
			return;
		}
		Object val = (Object)((obj is Object) ? obj : null);
		if ((val != (Object)null && val == (Object)null) || !_visited.Add(obj))
		{
			return;
		}
		onField(path, obj);
		foreach (FieldInfo item in SafeFields(type))
		{
			try
			{
				object value = item.GetValue(obj);
				if (value != null)
				{
					string path2 = path + "." + item.Name;
					WalkInternal(value, path2, depth + 1, onField);
				}
			}
			catch
			{
			}
		}
		if (!(obj is IEnumerable enumerable) || obj is string)
		{
			return;
		}
		int num = 0;
		foreach (object item2 in enumerable)
		{
			if (item2 != null)
			{
				WalkInternal(item2, path + "[" + num + "]", depth + 1, onField);
				num++;
			}
		}
	}

	private static bool IsForbidden(Type t)
	{
		string text = t.FullName ?? t.Name;
		string[] forbiddenTypePrefixes = ForbiddenTypePrefixes;
		foreach (string value in forbiddenTypePrefixes)
		{
			if (text.StartsWith(value, StringComparison.Ordinal))
			{
				return true;
			}
		}
		return false;
	}

	private static IEnumerable<FieldInfo> SafeFields(Type t)
	{
		FieldInfo[] fields;
		try
		{
			fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}
		catch
		{
			yield break;
		}
		FieldInfo[] array = fields;
		FieldInfo[] array2 = array;
		foreach (FieldInfo fieldInfo in array2)
		{
			if (!fieldInfo.IsStatic && !fieldInfo.FieldType.IsPointer && !IsForbidden(fieldInfo.FieldType))
			{
				yield return fieldInfo;
			}
		}
	}
}
namespace WubarrksEye
{
	[BepInPlugin("wubarrk.theeye", "Wubarrk's Eye", "2.1.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "wubarrk.theeye";

		public const string PluginName = "Wubarrk's Eye";

		public const string PluginVersion = "2.1.1";

		private Harmony _harmony;

		private static ManualLogSource _log;

		public static ManualLogSource Log => _log;

		private void Awake()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			WubarrkLogger.Initialize(((BaseUnityPlugin)this).Logger);
			try
			{
				WubarrkConfig.Bind(((BaseUnityPlugin)this).Config);
				_log.LogInfo((object)"[Eye] WubarrkConfig bound.");
				_harmony = new Harmony("wubarrk.theeye");
				try
				{
					WubarrkLogger.Info("[Eye] Applying ZNetScene Area Overrides to force global ZDO existence...");
					HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(ZDOExistencePatch), "PrefixOutsideActiveArea", (Type[])null, (Type[])null));
					HarmonyMethod val2 = new HarmonyMethod(AccessTools.Method(typeof(ZDOExistencePatch), "PrefixInActiveArea1", (Type[])null, (Type[])null));
					HarmonyMethod val3 = new HarmonyMethod(AccessTools.Method(typeof(ZDOExistencePatch), "PrefixInActiveArea2", (Type[])null, (Type[])null));
					HarmonyMethod val4 = new HarmonyMethod(AccessTools.Method(typeof(ZDOExistencePatch), "PrefixInActiveArea3", (Type[])null, (Type[])null));
					MethodInfo methodInfo = AccessTools.Method(typeof(ZNetScene), "OutsideActiveArea", new Type[1] { typeof(Vector3) }, (Type[])null);
					MethodInfo methodInfo2 = AccessTools.Method(typeof(ZNetScene), "InActiveArea", new Type[2]
					{
						typeof(Vector2i),
						typeof(Vector3)
					}, (Type[])null);
					MethodInfo methodInfo3 = AccessTools.Method(typeof(ZNetScene), "InActiveArea", new Type[2]
					{
						typeof(Vector2i),
						typeof(Vector2i)
					}, (Type[])null);
					MethodInfo methodInfo4 = AccessTools.Method(typeof(ZNetScene), "InActiveArea", new Type[3]
					{
						typeof(Vector2i),
						typeof(Vector2i),
						typeof(int)
					}, (Type[])null);
					if (methodInfo == null || methodInfo2 == null || methodInfo3 == null || methodInfo4 == null)
					{
						throw new Exception("One or more ZNetScene ActiveArea methods could not be found via reflection.");
					}
					_harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_harmony.Patch((MethodBase)methodInfo2, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_harmony.Patch((MethodBase)methodInfo3, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_harmony.Patch((MethodBase)methodInfo4, val4, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					WubarrkLogger.Info("[Eye] <color=#00FF00>SUCCESS: ZNetScene Area Overrides applied. The Eye is fully open! No ghost ZDOs can hide.</color>");
				}
				catch (Exception ex)
				{
					WubarrkLogger.Error("[Eye] FAILED to apply ZNetScene Area Overrides. Exception: " + ex.Message);
					WubarrkLogger.Warn("[Eye] IMPACT: ZDO dumps may miss objects outside the active player area (Ghost ZDOs). Game will continue to load normally.");
				}
				_harmony.PatchAll();
				WubarrkLogger.Info("[Eye] General Harmony patches applied.");
				EyeCommands.Initialize(((BaseUnityPlugin)this).Logger);
				GameObject val5 = new GameObject("EyeUIManager");
				val5.AddComponent<EyeUIManager>();
				Object.DontDestroyOnLoad((Object)val5);
				_log.LogInfo((object)"[Eye] Plugin initialization complete. Wubarrk's Eye is now watching.");
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"[Eye] Plugin initialization failed: {arg}");
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (_harmony != null)
				{
					_harmony.UnpatchSelf();
					_log.LogInfo((object)"[Eye] Harmony patches unpatched on destroy.");
				}
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"[Eye] Failed during OnDestroy: {arg}");
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "WubarrksEye";

		public const string PLUGIN_NAME = "WubarrksEye";

		public const string PLUGIN_VERSION = "2.1.1";
	}
}
namespace WubarrksEye.HarmonyPatches
{
	internal static class HarmonyBootstrap
	{
		public static void ApplyAll(Harmony harmony)
		{
			if (harmony == null)
			{
				throw new ArgumentNullException("harmony");
			}
			try
			{
				Assembly assembly = typeof(HarmonyBootstrap).Assembly;
				WubarrkLogger.Info("[HarmonyBootstrap] Running PatchAllSafe for attribute-based patches...");
				HarmonyPatcher.PatchAllSafe(harmony, assembly);
				int num = harmony.GetPatchedMethods().Count();
				WubarrkLogger.Info($"[HarmonyBootstrap] Total patched methods after bootstrap: {num}");
			}
			catch (Exception arg)
			{
				WubarrkLogger.Warn($"[HarmonyBootstrap] Fatal error while applying patches: {arg}");
			}
		}
	}
	internal static class HarmonyPatcher
	{
		public static int PatchAllOverloads(Harmony harmony, Type targetType, string methodName, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
		{
			if (harmony == null)
			{
				throw new ArgumentNullException("harmony");
			}
			if (targetType == null)
			{
				throw new ArgumentNullException("targetType");
			}
			if (string.IsNullOrEmpty(methodName))
			{
				throw new ArgumentNullException("methodName");
			}
			MethodInfo[] array;
			try
			{
				array = (from m in targetType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
					where string.Equals(m.Name, methodName, StringComparison.Ordinal)
					select m).ToArray();
			}
			catch (Exception ex)
			{
				LoggerWarning("PatchAllOverloads: failed to enumerate methods on " + targetType.FullName + ": " + ex.Message);
				return 0;
			}
			if (array.Length == 0)
			{
				array = FindSimilarNamedMethods(targetType, methodName).ToArray();
				if (array.Length == 0)
				{
					LoggerDebug("PatchAllOverloads: no methods named or similar to '" + methodName + "' found on " + targetType.FullName + ".");
					return 0;
				}
				LoggerWarning("PatchAllOverloads: exact method '" + methodName + "' not found on " + targetType.FullName + ". " + string.Format("Using {0} similar method(s): {1}", array.Length, string.Join(", ", array.Select((MethodInfo m) => m.Name))));
			}
			int num = 0;
			MethodInfo[] array2 = array;
			foreach (MethodInfo methodInfo in array2)
			{
				if (!IsPatchable(methodInfo))
				{
					LoggerDebug("PatchAllOverloads: skipping non-patchable " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ")");
					continue;
				}
				try
				{
					harmony.Patch((MethodBase)methodInfo, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
					LoggerInfo("Patched " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ")");
				}
				catch (Exception ex2)
				{
					LoggerWarning("PatchAllOverloads: failed to patch " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + "): " + ex2.Message);
				}
			}
			return num;
		}

		public static bool PatchSpecificOverload(Harmony harmony, Type targetType, string methodName, Type[] parameterTypes, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
		{
			if (harmony == null)
			{
				throw new ArgumentNullException("harmony");
			}
			if (targetType == null)
			{
				throw new ArgumentNullException("targetType");
			}
			if (string.IsNullOrEmpty(methodName))
			{
				throw new ArgumentNullException("methodName");
			}
			parameterTypes = parameterTypes ?? Type.EmptyTypes;
			MethodInfo methodInfo = null;
			try
			{
				methodInfo = targetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
			}
			catch (AmbiguousMatchException)
			{
				LoggerWarning("PatchSpecificOverload: ambiguous match for " + targetType.FullName + "." + methodName + "(" + string.Join(", ", parameterTypes.Select((Type t) => t?.Name ?? "null")) + "). Consider PatchAllOverloads.");
				return false;
			}
			catch (Exception ex2)
			{
				LoggerWarning("PatchSpecificOverload: error resolving " + targetType.FullName + "." + methodName + ": " + ex2.Message);
				return false;
			}
			if (methodInfo == null)
			{
				methodInfo = FindMethodBySignatureShape(targetType, methodName, parameterTypes);
				if (methodInfo == null)
				{
					LoggerDebug("PatchSpecificOverload: method not found " + targetType.FullName + "." + methodName + "(" + string.Join(", ", parameterTypes.Select((Type t) => t?.Name ?? "null")) + ").");
					return false;
				}
				LoggerWarning("PatchSpecificOverload: using fallback method " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ") instead of missing " + methodName + ".");
			}
			if (!IsPatchable(methodInfo))
			{
				LoggerWarning("PatchSpecificOverload: method " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ") is not patchable (abstract/extern/no body).");
				return false;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null);
				LoggerInfo("Patched specific overload " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ")");
				return true;
			}
			catch (Exception ex3)
			{
				LoggerWarning("PatchSpecificOverload: failed to patch " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + "): " + ex3.Message);
				return false;
			}
		}

		public static int SafePatchMethods(Harmony harmony, IEnumerable<MethodBase> methods, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
		{
			if (harmony == null)
			{
				throw new ArgumentNullException("harmony");
			}
			if (methods == null)
			{
				throw new ArgumentNullException("methods");
			}
			int num = 0;
			foreach (MethodBase method in methods)
			{
				if (method == null)
				{
					continue;
				}
				if (!IsPatchable(method))
				{
					LoggerDebug("SafePatchMethods: skipping non-patchable " + method.DeclaringType?.FullName + "." + method.Name + "(" + ParamTypes(method) + ")");
					continue;
				}
				try
				{
					harmony.Patch(method, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
					LoggerInfo("Patched " + method.DeclaringType?.FullName + "." + method.Name + "(" + ParamTypes(method) + ")");
				}
				catch (Exception ex)
				{
					LoggerWarning("SafePatchMethods: failed to patch " + method.DeclaringType?.FullName + "." + method.Name + "(" + ParamTypes(method) + "): " + ex.Message);
				}
			}
			return num;
		}

		public static void PatchAllSafe(Harmony harmony, Assembly assembly)
		{
			if (harmony == null)
			{
				throw new ArgumentNullException("harmony");
			}
			if (assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}
			Type[] array;
			try
			{
				array = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				array = ex.Types.Where((Type t) => t != null).ToArray();
			}
			catch (Exception ex2)
			{
				LoggerWarning("PatchAllSafe: failed to enumerate types in assembly: " + ex2.Message);
				return;
			}
			int num = 0;
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				if (type == null || !type.IsClass)
				{
					continue;
				}
				object[] array3 = type.GetCustomAttributes(inherit: false).Where(delegate(object a)
				{
					string fullName = a.GetType().FullName;
					return (fullName != null && fullName.StartsWith("HarmonyLib.HarmonyPatch")) || (a.GetType().FullName?.Contains("HarmonyPatch") ?? false);
				}).ToArray();
				if (array3.Length != 0)
				{
					try
					{
						int num3 = SafePatchClass(harmony, type, array3);
						num += num3;
					}
					catch (Exception ex3)
					{
						LoggerWarning("PatchAllSafe: error processing patch class " + type.FullName + ": " + ex3.Message);
					}
				}
			}
			LoggerInfo($"PatchAllSafe: completed. Total patched methods: {num}");
		}

		private static int SafePatchClass(Harmony harmony, Type patchClass, object[] patchAttrs)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (harmony == null)
			{
				throw new ArgumentNullException("harmony");
			}
			if (patchClass == null)
			{
				throw new ArgumentNullException("patchClass");
			}
			int patchedCount = 0;
			if (patchAttrs.Any((object a) => a.GetType().Name == "HarmonyPatchAllAttribute"))
			{
				LoggerDebug("SafePatchClass: skipping HarmonyPatchAll on " + patchClass.FullName + " (too broad).");
				return 0;
			}
			object[] array = patchAttrs.Where((object a) => a.GetType().Name == "HarmonyPatchAttribute").ToArray();
			if (array.Length == 0)
			{
				try
				{
					new PatchClassProcessor(harmony, patchClass).Patch();
					LoggerInfo("SafePatchClass: PatchClassProcessor applied for " + patchClass.FullName + ".");
					return 1;
				}
				catch (Exception ex)
				{
					LoggerWarning("SafePatchClass: PatchClassProcessor failed for " + patchClass.FullName + ": " + ex.Message);
					return 0;
				}
			}
			object[] array2 = array;
			foreach (object attr in array2)
			{
				try
				{
					if (!TryProcessHarmonyPatchAttribute(harmony, patchClass, attr, ref patchedCount))
					{
						LoggerDebug("SafePatchClass: HarmonyPatch on " + patchClass.FullName + " could not be resolved; skipped.");
					}
				}
				catch (Exception ex2)
				{
					LoggerWarning("SafePatchClass: error processing HarmonyPatch attribute on " + patchClass.FullName + ": " + ex2.Message);
				}
			}
			return patchedCount;
		}

		private static bool TryProcessHarmonyPatchAttribute(Harmony harmony, Type patchClass, object attr, ref int patchedCount)
		{
			Type type = attr.GetType();
			PropertyInfo propertyInfo = type.GetProperty("info") ?? type.GetProperty("Info");
			if (propertyInfo != null)
			{
				object value = propertyInfo.GetValue(attr);
				if (value != null)
				{
					return ProcessHarmonyPatchInfo(harmony, patchClass, value, ref patchedCount);
				}
			}
			FieldInfo? obj = type.GetField("declaringType") ?? type.GetField("DeclaringType");
			FieldInfo fieldInfo = type.GetField("methodName") ?? type.GetField("MethodName");
			FieldInfo fieldInfo2 = type.GetField("argumentTypes") ?? type.GetField("ArgumentTypes");
			Type type2 = obj?.GetValue(attr) as Type;
			string text = fieldInfo?.GetValue(attr) as string;
			Type[] argTypes = fieldInfo2?.GetValue(attr) as Type[];
			if (type2 == null || string.IsNullOrEmpty(text))
			{
				return false;
			}
			return ProcessTargetSpec(harmony, patchClass, type2, text, argTypes, ref patchedCount);
		}

		private static bool ProcessHarmonyPatchInfo(Harmony harmony, Type patchClass, object info, ref int patchedCount)
		{
			Type type = info.GetType();
			PropertyInfo propertyInfo = type.GetProperty("declaringType") ?? type.GetProperty("DeclaringType");
			PropertyInfo propertyInfo2 = type.GetProperty("methodName") ?? type.GetProperty("MethodName");
			PropertyInfo propertyInfo3 = type.GetProperty("argumentTypes") ?? type.GetProperty("ArgumentTypes");
			Type type2 = null;
			string text = null;
			Type[] argTypes = null;
			if (propertyInfo != null)
			{
				type2 = propertyInfo.GetValue(info) as Type;
			}
			if (propertyInfo2 != null)
			{
				text = propertyInfo2.GetValue(info) as string;
			}
			if (propertyInfo3 != null)
			{
				argTypes = propertyInfo3.GetValue(info) as Type[];
			}
			if (type2 == null || string.IsNullOrEmpty(text))
			{
				return false;
			}
			return ProcessTargetSpec(harmony, patchClass, type2, text, argTypes, ref patchedCount);
		}

		private static bool ProcessTargetSpec(Harmony harmony, Type patchClass, Type targetType, string methodName, Type[] argTypes, ref int patchedCount)
		{
			HarmonyMethod harmonyMethodFromPatchClass = GetHarmonyMethodFromPatchClass(patchClass, "Prefix");
			HarmonyMethod harmonyMethodFromPatchClass2 = GetHarmonyMethodFromPatchClass(patchClass, "Postfix");
			HarmonyMethod harmonyMethodFromPatchClass3 = GetHarmonyMethodFromPatchClass(patchClass, "Transpiler");
			if (argTypes != null && argTypes.Length != 0)
			{
				MethodInfo methodInfo = null;
				try
				{
					methodInfo = targetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, argTypes, null);
				}
				catch (AmbiguousMatchException)
				{
					LoggerWarning("SafePatchClass: ambiguous match for " + targetType.FullName + "." + methodName + " with specified args; attempting signature-shape fallback.");
				}
				if (methodInfo == null)
				{
					methodInfo = FindMethodBySignatureShape(targetType, methodName, argTypes);
				}
				if (methodInfo == null)
				{
					LoggerDebug("SafePatchClass: method not found " + targetType.FullName + "." + methodName + "(" + string.Join(", ", argTypes.Select((Type t) => t?.Name ?? "null")) + ").");
					return false;
				}
				if (!IsPatchable(methodInfo))
				{
					LoggerDebug("SafePatchClass: target not patchable " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + "); skipping.");
					return false;
				}
				try
				{
					harmony.Patch((MethodBase)methodInfo, harmonyMethodFromPatchClass, harmonyMethodFromPatchClass2, harmonyMethodFromPatchClass3, (HarmonyMethod)null, (HarmonyMethod)null);
					patchedCount++;
					LoggerInfo("SafePatchClass: patched " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ") via " + patchClass.FullName);
					return true;
				}
				catch (Exception ex2)
				{
					LoggerWarning("SafePatchClass: failed to patch " + targetType.FullName + "." + methodInfo.Name + ": " + ex2.Message);
					return false;
				}
			}
			int num = PatchAllOverloads(harmony, targetType, methodName, harmonyMethodFromPatchClass, harmonyMethodFromPatchClass2, harmonyMethodFromPatchClass3);
			patchedCount += num;
			return num > 0;
		}

		private static HarmonyMethod GetHarmonyMethodFromPatchClass(Type patchClass, string methodName)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			try
			{
				MethodInfo method = patchClass.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					return null;
				}
				return new HarmonyMethod(method);
			}
			catch
			{
				return null;
			}
		}

		public static bool IsPatchable(MethodBase method)
		{
			if (method == null)
			{
				return false;
			}
			if (method.IsAbstract)
			{
				return false;
			}
			if ((method.Attributes & MethodAttributes.PinvokeImpl) != MethodAttributes.PrivateScope)
			{
				return false;
			}
			MethodInfo methodInfo = method as MethodInfo;
			if (methodInfo != null)
			{
				try
				{
					if (methodInfo.GetMethodBody() == null)
					{
						return false;
					}
				}
				catch
				{
					return false;
				}
			}
			return true;
		}

		private static string ParamTypes(MethodBase m)
		{
			try
			{
				return string.Join(", ", from p in m.GetParameters()
					select p.ParameterType.Name);
			}
			catch
			{
				return "";
			}
		}

		private static void LoggerInfo(string msg)
		{
			try
			{
				WubarrkLogger.Info("[HarmonyPatcher] " + msg);
			}
			catch
			{
			}
		}

		private static void LoggerWarning(string msg)
		{
			try
			{
				WubarrkLogger.Warn("[HarmonyPatcher] " + msg);
			}
			catch
			{
			}
		}

		private static void LoggerDebug(string msg)
		{
			try
			{
				WubarrkLogger.Info("[HarmonyPatcher][Debug] " + msg);
			}
			catch
			{
			}
		}

		private static IEnumerable<MethodInfo> FindSimilarNamedMethods(Type type, string methodName)
		{
			MethodInfo[] methods;
			try
			{
				methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			catch
			{
				yield break;
			}
			string target = methodName.ToLowerInvariant();
			MethodInfo[] array = methods;
			MethodInfo[] array2 = array;
			foreach (MethodInfo methodInfo in array2)
			{
				string text = methodInfo.Name.ToLowerInvariant();
				if (!(text == target) && (text.Contains(target) || target.Contains(text) || LevenshteinDistance(text, target) <= 2))
				{
					yield return methodInfo;
				}
			}
		}

		private static MethodInfo FindMethodBySignatureShape(Type type, string originalName, Type[] parameterTypes)
		{
			MethodInfo[] methods;
			try
			{
				methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			catch
			{
				return null;
			}
			string target = originalName.ToLowerInvariant();
			MethodInfo methodInfo = (from m in methods
				where ParametersMatchExactly(m, parameterTypes)
				orderby LevenshteinDistance(m.Name.ToLowerInvariant(), target)
				select m).FirstOrDefault();
			if (methodInfo != null)
			{
				return methodInfo;
			}
			return (from m in methods
				where m.GetParameters().Length == parameterTypes.Length
				orderby LevenshteinDistance(m.Name.ToLowerInvariant(), target)
				select m).FirstOrDefault();
		}

		private static bool ParametersMatchExactly(MethodBase m, Type[] parameterTypes)
		{
			ParameterInfo[] parameters = m.GetParameters();
			if (parameters.Length != parameterTypes.Length)
			{
				return false;
			}
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].ParameterType != parameterTypes[i])
				{
					return false;
				}
			}
			return true;
		}

		private static int LevenshteinDistance(string a, string b)
		{
			if (string.IsNullOrEmpty(a))
			{
				return b?.Length ?? 0;
			}
			if (string.IsNullOrEmpty(b))
			{
				return a.Length;
			}
			int[,] array = new int[a.Length + 1, b.Length + 1];
			for (int i = 0; i <= a.Length; i++)
			{
				array[i, 0] = i;
			}
			for (int j = 0; j <= b.Length; j++)
			{
				array[0, j] = j;
			}
			for (int k = 1; k <= a.Length; k++)
			{
				for (int l = 1; l <= b.Length; l++)
				{
					int num = ((a[k - 1] != b[l - 1]) ? 1 : 0);
					array[k, l] = Math.Min(Math.Min(array[k - 1, l] + 1, array[k, l - 1] + 1), array[k - 1, l - 1] + num);
				}
			}
			return array[a.Length, b.Length];
		}
	}
}
namespace WubarrksEye.Core
{
	internal static class ApiDumpWriter
	{
		public static void WriteTypeApi(TextWriter w, Type type)
		{
			if (type == null)
			{
				return;
			}
			AssemblyName name = type.Assembly.GetName();
			w.WriteLine("=== API BEGIN ===");
			w.WriteLine("Type: " + type.FullName);
			w.WriteLine("Namespace: " + (type.Namespace ?? "<none>"));
			w.WriteLine("Assembly: " + name.Name);
			w.WriteLine($"AssemblyVersion: {name.Version}");
			w.WriteLine("Kind: " + GetTypeKind(type));
			w.WriteLine($"IsAbstract: {type.IsAbstract}");
			w.WriteLine($"IsSealed: {type.IsSealed}");
			w.WriteLine($"IsGenericType: {type.IsGenericType}");
			Type[] array = (type.IsGenericType ? type.GetGenericArguments() : Type.EmptyTypes);
			w.WriteLine("GenericArguments:");
			if (array.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				Type[] array2 = array;
				foreach (Type type2 in array2)
				{
					w.WriteLine(type2.FullName ?? type2.Name);
				}
			}
			w.WriteLine("InheritanceChain:");
			foreach (Type item in GetInheritanceChain(type))
			{
				w.WriteLine(item.FullName ?? item.Name);
			}
			w.WriteLine("Implements:");
			Type[] interfaces = type.GetInterfaces();
			if (interfaces.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				foreach (Type item2 in interfaces.OrderBy((Type type3) => type3.FullName))
				{
					w.WriteLine(item2.FullName);
				}
			}
			w.WriteLine("Attributes:");
			List<string> list = SafeGetCustomAttributes(type);
			if (list.Count == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				foreach (string item3 in list)
				{
					w.WriteLine(item3);
				}
			}
			w.WriteLine("EnumValues:");
			if (type.IsEnum)
			{
				string[] names = Enum.GetNames(type);
				Array values = Enum.GetValues(type);
				for (int num = 0; num < names.Length; num++)
				{
					w.WriteLine($"{names[num]} = {(int)values.GetValue(num)}");
				}
			}
			else
			{
				w.WriteLine("<none>");
			}
			w.WriteLine("Fields:");
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (fields.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				foreach (FieldInfo item4 in fields.OrderBy((FieldInfo f) => f.Name))
				{
					w.WriteLine(item4.FieldType.FullName + " " + item4.Name + " " + GetFieldModifiers(item4));
				}
			}
			w.WriteLine("Properties:");
			PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (properties.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				foreach (PropertyInfo item5 in properties.OrderBy((PropertyInfo p) => p.Name))
				{
					w.WriteLine(item5.PropertyType.FullName + " " + item5.Name + " " + GetPropertyModifiers(item5) + " " + GetPropertyAccessorFlags(item5));
				}
			}
			w.WriteLine("Events:");
			EventInfo[] events = type.GetEvents(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (events.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				foreach (EventInfo item6 in events.OrderBy((EventInfo e) => e.Name))
				{
					w.WriteLine(item6.EventHandlerType.FullName + " " + item6.Name + " " + GetMethodModifiers(item6.GetAddMethod(nonPublic: true)));
				}
			}
			w.WriteLine("Methods:");
			MethodInfo[] array3 = (from methodInfo in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where !methodInfo.IsSpecialName
				orderby methodInfo.Name, methodInfo.GetParameters().Length
				select methodInfo).ToArray();
			if (array3.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				MethodInfo[] array4 = array3;
				foreach (MethodInfo m in array4)
				{
					w.WriteLine(FormatFullMethodSignature(m));
				}
			}
			w.WriteLine("UnityMetadata:");
			w.WriteLine($"IsMonoBehaviour: {typeof(MonoBehaviour).IsAssignableFrom(type)}");
			w.WriteLine($"IsScriptableObject: {typeof(ScriptableObject).IsAssignableFrom(type)}");
			w.WriteLine("RequiredComponents:");
			RequireComponent[] array5 = type.GetCustomAttributes(inherit: true).OfType<RequireComponent>().ToArray();
			if (array5.Length == 0)
			{
				w.WriteLine("<none>");
			}
			else
			{
				RequireComponent[] array6 = array5;
				foreach (RequireComponent val in array6)
				{
					if (val.m_Type0 != null)
					{
						w.WriteLine(val.m_Type0.FullName);
					}
					if (val.m_Type1 != null)
					{
						w.WriteLine(val.m_Type1.FullName);
					}
					if (val.m_Type2 != null)
					{
						w.WriteLine(val.m_Type2.FullName);
					}
				}
			}
			w.WriteLine("=== API END ===");
		}

		private static string GetTypeKind(Type t)
		{
			if (t.IsInterface)
			{
				return "interface";
			}
			if (t.IsEnum)
			{
				return "enum";
			}
			if (t.IsValueType)
			{
				return "struct";
			}
			return "class";
		}

		private static IEnumerable<Type> GetInheritanceChain(Type t)
		{
			while (t != null)
			{
				yield return t;
				t = t.BaseType;
			}
		}

		private static List<string> SafeGetCustomAttributes(MemberInfo m)
		{
			try
			{
				return (from a in m.GetCustomAttributes(inherit: true)
					select a.GetType().FullName).ToList();
			}
			catch
			{
				return new List<string>();
			}
		}

		private static string GetFieldModifiers(FieldInfo f)
		{
			List<string> list = new List<string>();
			list.Add("[" + (f.IsPublic ? "public" : (f.IsFamily ? "protected" : (f.IsAssembly ? "internal" : (f.IsPrivate ? "private" : "unknown")))));
			if (f.IsStatic)
			{
				list.Add("static");
			}
			if (f.IsInitOnly)
			{
				list.Add("readonly");
			}
			if (f.IsLiteral && !f.IsInitOnly)
			{
				list.Add("const");
			}
			list.Add("]");
			return string.Join(" ", list);
		}

		private static string GetPropertyModifiers(PropertyInfo p)
		{
			MethodInfo methodInfo = p.GetGetMethod(nonPublic: true) ?? p.GetSetMethod(nonPublic: true);
			if (!(methodInfo != null))
			{
				return "";
			}
			return GetMethodModifiers(methodInfo);
		}

		private static string GetPropertyAccessorFlags(PropertyInfo p)
		{
			MethodInfo getMethod = p.GetGetMethod(nonPublic: true);
			MethodInfo setMethod = p.GetSetMethod(nonPublic: true);
			if (getMethod == null && setMethod == null)
			{
				return "";
			}
			List<string> list = new List<string>();
			if (getMethod != null)
			{
				list.Add(GetVisibility(getMethod) + " get");
			}
			if (setMethod != null)
			{
				list.Add(GetVisibility(setMethod) + " set");
			}
			return "{" + string.Join(", ", list) + "}";
		}

		private static string GetVisibility(MethodBase m)
		{
			if (m.IsPublic)
			{
				return "public";
			}
			if (m.IsFamily)
			{
				return "protected";
			}
			if (m.IsAssembly)
			{
				return "internal";
			}
			if (m.IsPrivate)
			{
				return "private";
			}
			return "unknown";
		}

		private static string GetMethodModifiers(MethodBase m)
		{
			List<string> list = new List<string>();
			list.Add("[" + GetVisibility(m));
			if (m.IsStatic)
			{
				list.Add("static");
			}
			if (m is MethodInfo methodInfo)
			{
				if (methodInfo.IsAbstract)
				{
					list.Add("abstract");
				}
				else if (methodInfo.IsVirtual && methodInfo.GetBaseDefinition() != methodInfo && !methodInfo.IsFinal)
				{
					list.Add("override");
				}
				else if (methodInfo.IsVirtual && !methodInfo.IsAbstract && !methodInfo.IsFinal)
				{
					list.Add("virtual");
				}
			}
			list.Add("]");
			return string.Join(" ", list);
		}

		private static string FormatFullMethodSignature(MethodInfo m)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(GetMethodModifiers(m));
			stringBuilder.Append(' ');
			stringBuilder.Append(m.ReturnType.FullName);
			stringBuilder.Append(' ');
			stringBuilder.Append(m.Name);
			if (m.IsGenericMethod)
			{
				Type[] genericArguments = m.GetGenericArguments();
				stringBuilder.Append('<');
				stringBuilder.Append(string.Join(", ", genericArguments.Select((Type a) => a.FullName ?? a.Name)));
				stringBuilder.Append('>');
			}
			stringBuilder.Append('(');
			ParameterInfo[] parameters = m.GetParameters();
			for (int num = 0; num < parameters.Length; num++)
			{
				if (num > 0)
				{
					stringBuilder.Append(", ");
				}
				ParameterInfo parameterInfo = parameters[num];
				if (parameterInfo.IsOut)
				{
					stringBuilder.Append("out ");
				}
				else if (parameterInfo.ParameterType.IsByRef)
				{
					stringBuilder.Append("ref ");
				}
				stringBuilder.Append(parameterInfo.ParameterType.FullName ?? parameterInfo.ParameterType.Name);
				stringBuilder.Append(' ');
				stringBuilder.Append(parameterInfo.Name);
			}
			stringBuilder.Append(')');
			return stringBuilder.ToString();
		}
	}
	internal static class EyeCommands
	{
		private static ManualLogSource _logger;

		public static void Initialize(ManualLogSource logger)
		{
			_logger = logger ?? throw new ArgumentNullException("logger");
			RegisterCommand("dump_eye", DumpEye);
			_logger.LogInfo((object)"[Eye/Commands] EyeCommands initialized.");
		}

		private static void RegisterCommand(string name, Action<string[]> handler)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				new ConsoleCommand(name, "Wubarrk's Eye: " + name, (ConsoleEvent)delegate(ConsoleEventArgs args)
				{
					handler(args.Args);
				}, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				_logger.LogInfo((object)("[Eye/Commands] Registered command: " + name));
			}
			catch (Exception arg)
			{
				_logger.LogError((object)$"[Eye/Commands] Failed to register command '{name}': {arg}");
			}
		}

		private static void DumpEye(string[] args)
		{
			try
			{
				_logger.LogInfo((object)"[Eye/Commands] dump_eye invoked.");
				string path = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
				string dumpRoot = Path.Combine(Paths.ConfigPath, "WubarrksEye_Dumps", path);
				DumpManager.DumpOptions options = new DumpManager.DumpOptions
				{
					DumpAgentML = true,
					DumpAPI = true,
					DumpPrefabs = true,
					DumpScene = true,
					DumpZDOs = true,
					DumpObjectDB = true,
					DumpValues = true,
					DumpCallGraph = true,
					RunHuginnsReport = true,
					HuginnsReportMLFormat = true
				};
				DumpManager.Start(dumpRoot, options);
			}
			catch (Exception arg)
			{
				_logger.LogError((object)$"[Eye/Commands] dump_eye failed: {arg}");
			}
		}
	}
	internal static class WubarrkConfig
	{
		public enum RamProfile
		{
			Rig_16GB,
			Rig_32GB,
			Rig_64GB_Plus
		}

		public static ConfigEntry<bool> EnableMod;

		public static ConfigEntry<string> PhysicsAuthorityMode;

		public static ConfigEntry<int> DumpMaxFileSizeMB;

		public static ConfigEntry<bool> DeepDiagnostics;

		public static ConfigEntry<int> BurstObjectsPerFrame;

		public static ConfigEntry<RamProfile> SystemMemoryProfile;

		public static ConfigEntry<int> DifferThreadCount;

		public static void Bind(ConfigFile Config)
		{
			EnableMod = Config.Bind<bool>("Core", "EnableMod", true, "Turns the mod on or off. Leave this on unless you're troubleshooting.");
			PhysicsAuthorityMode = Config.Bind<string>("Core", "PhysicsAuthorityMode", "server", "Who controls physics: the server or the client. If you don't know, leave it alone.");
			DumpMaxFileSizeMB = Config.Bind<int>("Storage", "DumpMaxFileSizeMB", 1024, "Maximum file size for a single JSON dump file in MB before it splits. Default 1024 (1GB).");
			if (DumpMaxFileSizeMB.Value <= 0 || DumpMaxFileSizeMB.Value > 10240)
			{
				DumpMaxFileSizeMB.Value = 1024;
			}
			DeepDiagnostics = Config.Bind<bool>("Diagnostics", "DeepDiagnostics", false, "Extra logging and extra detail. Helps debugging. Slows things down.");
			BurstObjectsPerFrame = Config.Bind<int>("Performance", "BurstObjectsPerFrame", 50, "How many objects the Async Deep Scanner processes per frame. Lower this if the game stutters during a dump.");
			SystemMemoryProfile = Config.Bind<RamProfile>("Hardware", "SystemMemoryProfile", RamProfile.Rig_16GB, "Select your system RAM. Higher profiles drastically speed up processing but will consume more RAM. Default is 16GB (Safe Mode).");
			DifferThreadCount = Config.Bind<int>("Hardware", "DifferThreadCount", 4, "Number of CPU threads Huginn's Report uses for diffing. Clamped between 1 and 16.");
			if (DifferThreadCount.Value < 1)
			{
				DifferThreadCount.Value = 1;
			}
			if (DifferThreadCount.Value > 16)
			{
				DifferThreadCount.Value = 16;
			}
		}
	}
	internal static class WubarrkLogger
	{
		internal static void Initialize(ManualLogSource log)
		{
		}

		private static string Colorize(string message)
		{
			try
			{
				if (message.Contains("[Eye]"))
				{
					return "<color=#00FFFF>" + message + "</color>";
				}
				if (message.Contains("[Error]"))
				{
					return "<color=#FF0000>" + message + "</color>";
				}
				return message;
			}
			catch
			{
				return message;
			}
		}

		internal static void Info(string message)
		{
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)Colorize("[WubarrksEye] " + message));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[Eye] Logger Failed: {arg}");
				}
			}
		}

		internal static void Warn(string message)
		{
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)Colorize("[WubarrksEye] " + message));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[Eye] Logger Failed: {arg}");
				}
			}
		}

		internal static void Error(string message)
		{
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)Colorize("[WubarrksEye] " + message));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[Eye] Logger Failed: {arg}");
				}
			}
		}

		internal static void MaskedError(string message)
		{
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)Colorize("[WubarrksEye] " + message));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[Eye] Logger Failed: {arg}");
				}
			}
		}
	}
}
namespace WubarrksEye.Core.UI
{
	public class EyeUIManager : MonoBehaviour
	{
		private bool _showConfigWindow;

		private bool _showHud = true;

		public static bool DumpAgentMLOptions = false;

		public static bool DumpApiOptions = true;

		public static bool DumpPrefabsOptions = true;

		public static bool DumpSceneOptions = true;

		public static bool DumpZDOOptions = true;

		public static bool DumpObjectDBOptions = true;

		public static bool DumpValuesOptions = true;

		public static bool DumpCallGraphOptions = true;

		public static bool HuginnsReportEnabled = false;

		public static bool HuginnsReportMLFormat = true;

		private Rect _windowRect = new Rect(20f, 20f, 450f, 400f);

		private Rect _hudRect = new Rect(20f, 20f, 300f, 100f);

		private GUIStyle _windowStyle;

		private GUIStyle _labelStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _buttonStyle;

		private bool _stylesInitialized;

		public static EyeUIManager Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			WubarrkLogger.Info("[Eye.UI] UIManager initialized. Press F8 to toggle Config window, F9 to toggle HUD.");
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)289))
			{
				_showConfigWindow = !_showConfigWindow;
			}
			if (Input.GetKeyDown((KeyCode)290))
			{
				_showHud = !_showHud;
			}
		}

		private void InitializeStyles()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			if (!_stylesInitialized)
			{
				Texture2D val = new Texture2D(1, 1);
				val.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.85f));
				val.Apply();
				Texture2D val2 = new Texture2D(1, 1);
				val2.SetPixel(0, 0, new Color(0.2f, 0.2f, 0.2f, 0.9f));
				val2.Apply();
				_windowStyle = new GUIStyle(GUI.skin.window);
				_windowStyle.normal.background = val;
				_windowStyle.normal.textColor = new Color(1f, 0.84f, 0f);
				_windowStyle.focused.textColor = new Color(1f, 0.84f, 0f);
				_windowStyle.onNormal.textColor = new Color(1f, 0.84f, 0f);
				_labelStyle = new GUIStyle(GUI.skin.label);
				_labelStyle.normal.textColor = new Color(1f, 0.84f, 0f);
				_headerStyle = new GUIStyle(GUI.skin.label);
				_headerStyle.normal.textColor = new Color(1f, 0.84f, 0f);
				_headerStyle.fontStyle = (FontStyle)1;
				_headerStyle.fontSize = 14;
				_buttonStyle = new GUIStyle(GUI.skin.button);
				_buttonStyle.normal.background = val2;
				_buttonStyle.normal.textColor = new Color(1f, 0.84f, 0f);
				_stylesInitialized = true;
			}
		}

		private void OnGUI()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			InitializeStyles();
			if (_showHud && !_showConfigWindow)
			{
				DrawHUD();
			}
			if (_showConfigWindow)
			{
				_windowRect = GUI.Window(9999, _windowRect, new WindowFunction(DrawConfigWindow), "TheEye - Developer Console", _windowStyle);
			}
		}

		private void DrawHUD()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			GUI.Box(_hudRect, "", _windowStyle);
			GUILayout.BeginArea(_hudRect);
			GUILayout.Label("TheEye HUD", _headerStyle, Array.Empty<GUILayoutOption>());
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				int num = ((ZDOMan.instance != null) ? ZDOMan.instance.m_objectsByID.Count : 0);
				GUILayout.Label($"Active ZDOs: {num}", _labelStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Waiting for game...", _labelStyle, Array.Empty<GUILayoutOption>());
			}
			if (DumpManager.IsRunning)
			{
				GUILayout.Label($"Total Progress: {DumpManager.OverallProgress:F1}%", _labelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Phase: {DumpManager.CurrentPhase} ({DumpManager.ProgressPercentage:F0}%)", _labelStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Status: Idle", _labelStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndArea();
		}

		private void DrawConfigWindow(int windowID)
		{
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Deep Dump Controls", _headerStyle, Array.Empty<GUILayoutOption>());
			if (DumpManager.IsRunning)
			{
				GUILayout.Label($"Total Progress: {DumpManager.OverallProgress:F1}%", _labelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Phase: {DumpManager.CurrentPhase} ({DumpManager.ProgressPercentage:F0}%)", _labelStyle, Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Cancel Dump", _buttonStyle, Array.Empty<GUILayoutOption>()))
				{
					DumpManager.Cancel();
				}
			}
			else
			{
				DumpAgentMLOptions = GUILayout.Toggle(DumpAgentMLOptions, "AI Agent ML Dump (Complete Consolidated State)", Array.Empty<GUILayoutOption>());
				if (DumpAgentMLOptions)
				{
					GUILayout.Label("<color=#888888>AI Dump active. Standard dumps disabled.</color>", _labelStyle, Array.Empty<GUILayoutOption>());
				}
				else
				{
					DumpApiOptions = GUILayout.Toggle(DumpApiOptions, "Dump API / Types (Reflection)", Array.Empty<GUILayoutOption>());
					DumpPrefabsOptions = GUILayout.Toggle(DumpPrefabsOptions, "Dump Prefabs (Detailed)", Array.Empty<GUILayoutOption>());
					DumpSceneOptions = GUILayout.Toggle(DumpSceneOptions, "Dump Active Scene Objects", Array.Empty<GUILayoutOption>());
					DumpZDOOptions = GUILayout.Toggle(DumpZDOOptions, "Dump ZDO State", Array.Empty<GUILayoutOption>());
					DumpObjectDBOptions = GUILayout.Toggle(DumpObjectDBOptions, "Dump ObjectDB (Items & Recipes)", Array.Empty<GUILayoutOption>());
					DumpValuesOptions = GUILayout.Toggle(DumpValuesOptions, "Dump Values (field contents)", Array.Empty<GUILayoutOption>());
					DumpCallGraphOptions = GUILayout.Toggle(DumpCallGraphOptions, "Dump Call Graph (IL call / field edges)", Array.Empty<GUILayoutOption>());
				}
				GUILayout.Space(10f);
				GUILayout.Label("<color=#FF5555>Experimental Features</color>", _headerStyle, Array.Empty<GUILayoutOption>());
				HuginnsReportEnabled = GUILayout.Toggle(HuginnsReportEnabled, "<color=#FF9999>[EXPERIMENTAL]</color> Enable Huginn's Report (Diff-er)", Array.Empty<GUILayoutOption>());
				if (HuginnsReportEnabled)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					if (GUILayout.Toggle(!HuginnsReportMLFormat, "Human Readable", Array.Empty<GUILayoutOption>()))
					{
						HuginnsReportMLFormat = false;
					}
					if (GUILayout.Toggle(HuginnsReportMLFormat, "AI Agent Format", Array.Empty<GUILayoutOption>()))
					{
						HuginnsReportMLFormat = true;
					}
					GUILayout.EndHorizontal();
				}
				GUILayout.Space(10f);
				if (GUILayout.Button("Start Dump", _buttonStyle, Array.Empty<GUILayoutOption>()))
				{
					DumpManager.DumpOptions options = new DumpManager.DumpOptions
					{
						DumpAgentML = DumpAgentMLOptions,
						DumpAPI = (DumpAgentMLOptions || DumpApiOptions),
						DumpPrefabs = (DumpAgentMLOptions || DumpPrefabsOptions),
						DumpScene = (DumpAgentMLOptions || DumpSceneOptions),
						DumpZDOs = (DumpAgentMLOptions || DumpZDOOptions),
						DumpObjectDB = (DumpAgentMLOptions || DumpObjectDBOptions),
						DumpValues = (DumpAgentMLOptions || DumpValuesOptions),
						DumpCallGraph = (DumpAgentMLOptions || DumpCallGraphOptions),
						RunHuginnsReport = HuginnsReportEnabled,
						HuginnsReportMLFormat = HuginnsReportMLFormat
					};
					string path = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
					DumpManager.Start(Path.Combine(Paths.ConfigPath, "WubarrksEye_Dumps", path), options);
				}
			}
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}
	}
}
namespace WubarrksEye.Core.Patches
{
	public static class ZDOExistencePatch
	{
		public static bool PrefixOutsideActiveArea(ref bool __result)
		{
			__result = false;
			return false;
		}

		public static bool PrefixInActiveArea1(ref bool __result)
		{
			__result = true;
			return false;
		}

		public static bool PrefixInActiveArea2(ref bool __result)
		{
			__result = true;
			return false;
		}

		public static bool PrefixInActiveArea3(ref bool __result)
		{
			__result = true;
			return false;
		}
	}
}
namespace WubarrksEye.Core.Dumpers
{
	public class CallGraphExtractor : IDataExtractor
	{
		private static OpCode[] _singleByteOpCodes;

		private static OpCode[] _twoByteOpCodes;

		public string ExtractorName => "Call Graph";

		public string OutputFileName => "CallGraph_Dump.json";

		public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
		{
			return Extract(writer, minifiedJsonl: false, maxBytes);
		}

		public IEnumerator ExtractDataToZip(StreamWriter writer)
		{
			return Extract(writer, minifiedJsonl: true, int.MaxValue);
		}

		private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl, int maxBytes)
		{
			Assembly assembly = typeof(ZNetScene).Assembly;
			Type[] types;
			try
			{
				types = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				types = ex.Types.Where((Type t) => t != null).ToArray();
			}
			catch (Exception ex2)
			{
				WubarrkLogger.Error("[Eye.CallGraph] Could not enumerate types in " + assembly.GetName().Name + ": " + ex2.Message);
				yield break;
			}
			Dictionary<string, List<string>> calledByMap = new Dictionary<string, List<string>>();
			int methodCount = 0;
			int typeIndex = 0;
			int batchSize = ((WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_32GB) ? 200 : ((WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_64GB_Plus) ? 1000 : 50));
			bool isFirst = true;
			long written = 0L;
			bool truncated = false;
			Type[] array = types;
			foreach (Type type in array)
			{
				if (DumpManager._cancelRequested || truncated)
				{
					break;
				}
				List<MethodBase> list;
				try
				{
					list = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Cast<MethodBase>().Concat(type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
						.ToList();
				}
				catch
				{
					typeIndex++;
					continue;
				}
				foreach (MethodBase item in list)
				{
					if (DumpManager._cancelRequested)
					{
						break;
					}
					if (written >= maxBytes)
					{
						truncated = true;
						break;
					}
					JObject val = null;
					try
					{
						val = WalkMethod(item, calledByMap);
					}
					catch (Exception ex3)
					{
						WubarrkLogger.Warn("[Eye.CallGraph] Skipped " + type.Name + "." + item.Name + ": " + ex3.GetType().Name);
					}
					if (val != null)
					{
						writeObj(val);
						methodCount++;
						if (methodCount % batchSize == 0)
						{
							writer.Flush();
							DumpManager._progress = (float)typeIndex / (float)Math.Max(1, types.Length) * 100f;
							yield return null;
						}
					}
				}
				typeIndex++;
			}
			if (truncated)
			{
				WubarrkLogger.Warn($"[Eye.CallGraph] Hit the {maxBytes / 1048576} MB cap after {methodCount} methods; forward edges truncated.");
			}
			foreach (KeyValuePair<string, List<string>> item2 in calledByMap)
			{
				if (DumpManager._cancelRequested)
				{
					break;
				}
				JObject val2 = new JObject
				{
					["Type"] = JToken.op_Implicit("Index"),
					["Kind"] = JToken.op_Implicit("CalledBy"),
					["Method"] = JToken.op_Implicit(item2.Key)
				};
				object[] array2 = item2.Value.Distinct().ToArray();
				val2["Callers"] = (JToken)new JArray(array2);
				writeObj(val2);
				methodCount++;
				if (methodCount % batchSize == 0)
				{
					writer.Flush();
					yield return null;
				}
			}
			writer.Flush();
			DumpManager._progress = 100f;
			WubarrkLogger.Info($"[Eye.CallGraph] {methodCount} records written across {types.Length} types.");
			void writeObj(JObject val3)
			{
				string text = ((JToken)val3).ToString((Formatting)(!minifiedJsonl), Array.Empty<JsonConverter>());
				if (minifiedJsonl)
				{
					writer.WriteLine(text);
				}
				else
				{
					if (!isFirst)
					{
						writer.Write(",\n");
					}
					writer.Write(text);
					isFirst = false;
				}
				written += text.Length + 2;
			}
		}

		private JObject WalkMethod(MethodBase method, Dictionary<string, List<string>> calledByMap)
		{
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Expected O, but got Unknown
			MethodBody methodBody = null;
			try
			{
				methodBody = method.GetMethodBody();
			}
			catch
			{
			}
			if (methodBody == null)
			{
				return null;
			}
			byte[] iLAsByteArray = methodBody.GetILAsByteArray();
			if (iLAsByteArray == null || iLAsByteArray.Length == 0)
			{
				return null;
			}
			Module module = method.Module;
			Type[] genericTypeArguments = ((method.DeclaringType != null && method.DeclaringType.IsGenericType) ? method.DeclaringType.GetGenericArguments() : null);
			Type[] genericMethodArguments = (method.IsGenericMethod ? method.GetGenericArguments() : null);
			string text = FormatSignature(method);
			string item = method.DeclaringType?.Name + "." + method.Name + "(" + string.Join(",", from p in method.GetParameters()
				select p.ParameterType.FullName ?? p.ParameterType.Name) + ")";
			JObject val = new JObject();
			val["Type"] = JToken.op_Implicit(method.DeclaringType?.Name ?? "Unknown");
			val["Method"] = JToken.op_Implicit(method.Name);
			val["Signature"] = JToken.op_Implicit(text);
			try
			{
				val["Token"] = JToken.op_Implicit(method.MetadataToken);
			}
			catch
			{
				val["Token"] = JToken.op_Implicit(0);
			}
			MethodInfo methodInfo = method as MethodInfo;
			bool flag = methodInfo != null && methodInfo.IsVirtual && methodInfo.GetBaseDefinition() != methodInfo;
			val["ChainsToBase"] = (JToken)(flag ? ((object)JToken.op_Implicit(false)) : ((object)JValue.CreateNull()));
			JArray val2 = new JArray();
			JArray val3 = new JArray();
			JArray val4 = new JArray();
			int num = 0;
			int num2 = 0;
			while (num2 < iLAsByteArray.Length)
			{
				OpCode opCode;
				if (iLAsByteArray[num2] == 254)
				{
					if (num2 + 1 >= iLAsByteArray.Length)
					{
						break;
					}
					opCode = _twoByteOpCodes[iLAsByteArray[num2 + 1]];
					num2 += 2;
				}
				else
				{
					opCode = _singleByteOpCodes[iLAsByteArray[num2]];
					num2++;
				}
				if (opCode.OperandType == OperandType.InlineMethod)
				{
					if (num2 + 4 > iLAsByteArray.Length)
					{
						break;
					}
					int metadataToken = BitConverter.ToInt32(iLAsByteArray, num2);
					num2 += 4;
					try
					{
						MethodBase methodBase = module.ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments);
						if (methodBase != null)
						{
							string text2 = methodBase.DeclaringType?.Name + "." + methodBase.Name + "(" + string.Join(",", from p in methodBase.GetParameters()
								select p.ParameterType.FullName ?? p.ParameterType.Name) + ")";
							JObject val5 = new JObject();
							val5["Target"] = JToken.op_Implicit(text2);
							val5["Op"] = JToken.op_Implicit(opCode.Name);
							val2.Add((JToken)(object)val5);
							if (!calledByMap.TryGetValue(text2, out var value))
							{
								value = (calledByMap[text2] = new List<string>());
							}
							value.Add(item);
							if (flag && opCode == OpCodes.Call && methodBase is MethodInfo methodInfo2 && methodInfo2.Name == methodInfo.Name && methodInfo2.DeclaringType != null && methodInfo.DeclaringType != null && methodInfo2.DeclaringType != methodInfo.DeclaringType && methodInfo2.DeclaringType.IsAssignableFrom(methodInfo.DeclaringType))
							{
								val["ChainsToBase"] = JToken.op_Implicit(true);
							}
						}
					}
					catch
					{
						num++;
					}
				}
				else if (opCode.OperandType == OperandType.InlineField)
				{
					if (num2 + 4 > iLAsByteArray.Length)
					{
						break;
					}
					int metadataToken2 = BitConverter.ToInt32(iLAsByteArray, num2);
					num2 += 4;
					try
					{
						FieldInfo fieldInfo = module.ResolveField(metadataToken2, genericTypeArguments, genericMethodArguments);
						if (fieldInfo != null)
						{
							string text3 = fieldInfo.DeclaringType?.Name + "." + fieldInfo.Name;
							if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldsfld || opCode == OpCodes.Ldflda || opCode == OpCodes.Ldsflda)
							{
								val3.Add(JToken.op_Implicit(text3));
							}
							else if (opCode == OpCodes.Stfld || opCode == OpCodes.Stsfld)
							{
								val4.Add(JToken.op_Implicit(text3));
							}
						}
					}
					catch
					{
						num++;
					}
				}
				else if (opCode.OperandType == OperandType.InlineSwitch)
				{
					if (num2 + 4 > iLAsByteArray.Length)
					{
						break;
					}
					int num3 = BitConverter.ToInt32(iLAsByteArray, num2);
					num2 += 4;
					num2 += num3 * 4;
				}
				else
				{
					switch (opCode.OperandType)
					{
					case OperandType.InlineBrTarget:
					case OperandType.InlineI:
					case OperandType.InlineSig:
					case OperandType.InlineString:
					case OperandType.InlineTok:
					case OperandType.InlineType:
					case OperandType.ShortInlineR:
						num2 += 4;
						break;
					case OperandType.InlineI8:
					case OperandType.InlineR:
						num2 += 8;
						break;
					case OperandType.InlineVar:
						num2 += 2;
						break;
					case OperandType.ShortInlineBrTarget:
					case OperandType.ShortInlineI:
					case OperandType.ShortInlineVar:
						num2++;
						break;
					}
				}
			}
			val["Calls"] = (JToken)(object)val2;
			val["Reads"] = (JToken)(object)val3;
			val["Writes"] = (JToken)(object)val4;
			val["Unresolved"] = JToken.op_Implicit(num);
			return val;
		}

		static CallGraphExtractor()
		{
			_singleByteOpCodes = new OpCode[256];
			_twoByteOpCodes = new OpCode[256];
			FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType != typeof(OpCode)))
				{
					OpCode opCode = (OpCode)fieldInfo.GetValue(null);
					ushort num = (ushort)opCode.Value;
					if (num < 256)
					{
						_singleByteOpCodes[num] = opCode;
					}
					else if ((num & 0xFF00) == 65024)
					{
						_twoByteOpCodes[num & 0xFF] = opCode;
					}
				}
			}
		}

		private string FormatSignature(MethodBase m)
		{
			string text = "";
			if (m.IsPublic)
			{
				text += "public ";
			}
			else if (m.IsFamily)
			{
				text += "protected ";
			}
			else if (m.IsAssembly)
			{
				text += "internal ";
			}
			else if (m.IsPrivate)
			{
				text += "private ";
			}
			if (m.IsStatic)
			{
				text += "static ";
			}
			else if (m.IsVirtual)
			{
				text = (((m.Attributes & MethodAttributes.VtableLayoutMask) == 0) ? (text + "override ") : (text + "virtual "));
			}
			if (m.IsAbstract)
			{
				text += "abstract ";
			}
			string text2 = "void";
			if (m is MethodInfo methodInfo)
			{
				text2 = methodInfo.ReturnType.FullName ?? methodInfo.ReturnType.Name;
			}
			IEnumerable<string> values = from x in m.GetParameters()
				select (x.ParameterType.FullName ?? x.ParameterType.Name) + " " + x.Name;
			return text + text2 + " " + m.Name + "(" + string.Join(", ", values) + ")";
		}
	}
	public interface IDataExtractor
	{
		string ExtractorName { get; }

		string OutputFileName { get; }

		IEnumerator ExtractData(StreamWriter writer, int maxBytes);

		IEnumerator ExtractDataToZip(StreamWriter writer);
	}
	public class ValueExtractor : IDataExtractor
	{
		internal static class Loc
		{
			private static bool _tried;

			private static object _instance;

			private static MethodInfo _localize;

			internal static string Resolve(string token)
			{
				if (string.IsNullOrEmpty(token))
				{
					return "";
				}
				if (token[0] != '$')
				{
					return token;
				}
				if (!_tried)
				{
					_tried = true;
					try
					{
						Type type = Type.GetType("Localization, assembly_valheim");
						if (type != null)
						{
							PropertyInfo property = type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public);
							if (property != null)
							{
								_instance = property.GetValue(null, null);
							}
							else
							{
								FieldInfo field = type.GetField("m_instance", BindingFlags.Static | BindingFlags.NonPublic);
								if (field != null)
								{
									_instance = field.GetValue(null);
								}
							}
							_localize = type.GetMethod("Localize", new Type[1] { typeof(string) });
						}
					}
					catch
					{
					}
				}
				if (_instance == null || _localize == null)
				{
					return token;
				}
				try
				{
					return (string)_localize.Invoke(_instance, new object[1] { token });
				}
				catch
				{
					return token;
				}
			}
		}

		internal static class Walker
		{
			private sealed class RefComparer : IEqualityComparer<object>
			{
				internal static readonly RefComparer Instance = new RefComparer();

				public new bool Equals(object a, object b)
				{
					return a == b;
				}

				public int GetHashCode(object o)
				{
					return RuntimeHelpers.GetHashCode(o);
				}
			}

			public const int MaxDepth = 4;

			public const int MaxCollection = 32;

			public const int NodeBudget = 25000;

			private static readonly string[] Forbidden = new string[16]
			{
				"PlayFab", "Steamworks", "System.Threading", "System.Net", "System.IO", "System.Reflection", "System.Runtime", "System.Security", "System.Diagnostics", "UnityEngine.Networking",
				"UnityEngine.AsyncOperation", "UnityEngine.ResourceRequest", "<>", "c__DisplayClass", "d__", "PrivateImplementationDetails"
			};

			private static HashSet<object> _seen;

			private static int _nodes;

			private static bool _blown;

			internal static void Walk(object root, string prefix, JObject w)
			{
				if (root != null)
				{
					if (_seen == null)
					{
						_seen = new HashSet<object>(RefComparer.Instance);
					}
					else
					{
						_seen.Clear();
					}
					_nodes = 0;
					_blown = false;
					try
					{
						Recurse(root, prefix, 0, w);
					}
					catch (Exception ex)
					{
						w[prefix + "<walk-error>"] = JToken.op_Implicit(ex.GetType().Name);
					}
					if (_blown)
					{
						w[prefix + "<budget-exceeded>"] = JToken.op_Implicit("stopped at " + _nodes + " nodes");
					}
					_seen.Clear();
				}
			}

			private static void Recurse(object obj, string prefix, int depth, JObject w)
			{
				if (obj == null || depth > 4 || _blown)
				{
					return;
				}
				Type type = obj.GetType();
				if (IsForbidden(type))
				{
					return;
				}
				foreach (FieldInfo item in Fields(type))
				{
					if (_blown)
					{
						break;
					}
					object value;
					try
					{
						value = item.GetValue(obj);
					}
					catch (Exception ex)
					{
						w[prefix + item.Name] = JToken.op_Implicit("<err:" + ex.GetType().Name + ">");
						continue;
					}
					Emit(value, prefix + item.Name, depth, w);
				}
			}

			private static void Emit(object v, string path, int depth, JObject w)
			{
				if (_blown)
				{
					return;
				}
				if (++_nodes > 25000)
				{
					_blown = true;
					return;
				}
				if (v == null)
				{
					w[path] = JToken.op_Implicit("");
					return;
				}
				Type type = v.GetType();
				Object val = (Object)((v is Object) ? v : null);
				if (val != null)
				{
					w[path] = JToken.op_Implicit((val == (Object)null) ? "<missing>" : val.name);
				}
				else if (IsScalar(type))
				{
					w[path] = JToken.op_Implicit(Scalar(v));
				}
				else if (v is IEnumerable)
				{
					bool flag = depth < 3;
					int num = 0;
					foreach (object item in (IEnumerable)v)
					{
						if (_blown)
						{
							return;
						}
						if (num >= 32)
						{
							w[path + ".<truncated>"] = JToken.op_Implicit("true");
							break;
						}
						if (flag)
						{
							Emit(item, path + "[" + num + "]", depth + 1, w);
						}
						else
						{
							w[path + "[" + num + "]"] = JToken.op_Implicit(Shallow(item));
						}
						num++;
					}
					w[path + ".<count>"] = JToken.op_Implicit(num.ToString(CultureInfo.InvariantCulture));
				}
				else if (depth >= 4 || IsForbidden(type))
				{
					w[path] = JToken.op_Implicit("<" + type.Name + ">");
				}
				else if (!type.IsValueType && !_seen.Add(v))
				{
					w[path] = JToken.op_Implicit("<cycle:" + type.Name + ">");
				}
				else
				{
					Recurse(v, path + ".", depth + 1, w);
				}
			}

			private static string Shallow(object e)
			{
				if (e == null)
				{
					return "";
				}
				Object val = (Object)((e is Object) ? e : null);
				if (val != null)
				{
					if (!(val == (Object)null))
					{
						return val.name;
					}
					return "<missing>";
				}
				Type type = e.GetType();
				if (!IsScalar(type))
				{
					return "<" + type.Name + ">";
				}
				return Scalar(e);
			}

			private static IEnumerable<FieldInfo> Fields(Type t)
			{
				try
				{
					return t.GetFields(BindingFlags.Instance | BindingFlags.Public);
				}
				catch
				{
					return new FieldInfo[0];
				}
			}

			private static bool IsScalar(Type t)
			{
				if (!t.IsPrimitive && !t.IsEnum && !(t == typeof(string)) && !(t == typeof(decimal)) && !(t == typeof(DateTime)) && !(t == typeof(Vector2)) && !(t == typeof(Vector3)) && !(t == typeof(Vector4)) && !(t == typeof(Quaternion)) && !(t == typeof(Color)))
				{
					return t == typeof(Color32);
				}
				return true;
			}

			private static string Scalar(object v)
			{
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: 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_0130: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0210: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_025f: Unknown result type (might be due to invalid IL or missing references)
				if (v is string)
				{
					return (string)v;
				}
				if (v is float num)
				{
					return num.ToString("R", CultureInfo.InvariantCulture);
				}
				if (v is double num2)
				{
					return num2.ToString("R", CultureInfo.InvariantCulture);
				}
				if (v is bool)
				{
					if (!(bool)v)
					{
						return "false";
					}
					return "true";
				}
				if (v is Enum)
				{
					return v.ToString();
				}
				if (v is Vector2 val)
				{
					return F(val.x) + "," + F(val.y);
				}
				if (v is Vector3 val2)
				{
					return F(val2.x) + "," + F(val2.y) + "," + F(val2.z);
				}
				if (v is Vector4 val3)
				{
					return F(val3.x) + "," + F(val3.y) + "," + F(val3.z) + "," + F(val3.w);
				}
				if (v is Quaternion val4)
				{
					return F(val4.x) + "," + F(val4.y) + "," + F(val4.z) + "," + F(val4.w);
				}
				if (v is Color val5)
				{
					return F(val5.r) + "," + F(val5.g) + "," + F(val5.b) + "," + F(val5.a);
				}
				if (v is Color32 val6)
				{
					return val6.r + "," + val6.g + "," + val6.b + "," + val6.a;
				}
				return Convert.ToString(v, CultureInfo.InvariantCulture);
			}

			private static string F(float f)
			{
				return f.ToString("R", CultureInfo.InvariantCulture);
			}

			private static bool IsForbidden(Type t)
			{
				string text = t.FullName ?? t.Name;
				for (int i = 0; i < Forbidden.Length; i++)
				{
					if (text.IndexOf(Forbidden[i], StringComparison.Ordinal) >= 0)
					{
						return true;
					}
				}
				return false;
			}

			internal static string NameOf(object o, params string[] candidates)
			{
				Type type = o.GetType();
				foreach (string name in candidates)
				{
					FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public);
					if (field == null)
					{
						continue;
					}
					object value;
					try
					{
						value = field.GetValue(o);
					}
					catch
					{
						continue;
					}
					if (value == null)
					{
						continue;
					}
					Object val = (Object)((value is Object) ? value : null);
					if (val != null)
					{
						if (val != (Object)null)
						{
							return val.name;
						}
						continue;
					}
					string text = value as string;
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
				return type.Name;
			}
		}

		public string ExtractorName => "Values";

		public string OutputFileName => "Values_Dump.json";

		public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
		{
			return Extract(writer, minifiedJsonl: false, maxBytes);
		}

		public IEnumerator ExtractDataToZip(StreamWriter writer)
		{
			return Extract(writer, minifiedJsonl: true, int.MaxValue);
		}

		private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl, int maxBytes)
		{
			bool isFirst = true;
			int n;
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				ObjectDB db = ObjectDB.instance;
				if (db.m_items != null && db.m_items.Count > 0)
				{
					n = 0;
					foreach (GameObject item in db.m_items)
					{
						if (DumpManager._cancelRequested)
						{
							yield break;
						}
						if ((Object)(object)item != (Object)null)
						{
							ItemDrop component = item.GetComponent<ItemDrop>();
							if ((Object)(object)component != (Object)null)
							{
								JObject val = new JObject();
								val["_Key"] = JToken.op_Implicit(((Object)item).name);
								val["_Source"] = JToken.op_Implicit("Items");
								val["_components"] = JToken.op_Implicit(string.Join("|", from c in item.GetComponents<Component>()
									where (Object)(object)c != (Object)null
									select ((object)c).GetType().Name));
								SharedData val2 = ((component.m_itemData != null) ? component.m_itemData.m_shared : null);
								if (val2 != null)
								{
									val["_displayName"] = JToken.op_Implicit(Loc.Resolve(val2.m_name));
									val["_displayDesc"] = JToken.op_Implicit(Loc.Resolve(val2.m_description));
								}
								Walker.Walk(component.m_itemData, "", val);
								writeObj(val);
							}
						}
						int num = n + 1;
						n = num;
						if (num % 10 == 0)
						{
							yield return null;
						}
					}
				}
				if (db.m_recipes != null && db.m_recipes.Count > 0)
				{
					n = 0;
					foreach (Recipe recipe in db.m_recipes)
					{
						if (!DumpManager._cancelRequested)
						{
							if ((Object)(object)recipe != (Object)null)
							{
								JObject val3 = new JObject();
								val3["_Key"] = JToken.op_Implicit(((Object)(object)recipe.m_item != (Object)null && (Object)(object)((Component)recipe.m_item).gameObject != (Object)null) ? ((Object)((Component)recipe.m_item).gameObject).name : ((Object)recipe).name);
								val3["_Source"] = JToken.op_Implicit("Recipes");
								Walker.Walk(recipe, "", val3);
								writeObj(val3);
							}
							int num = n + 1;
							n = num;
							if (num % 10 == 0)
							{
								yield return null;
							}
							continue;
						}
						yield break;
					}
				}
				if (db.m_StatusEffects != null && db.m_StatusEffects.Count > 0)
				{
					n = 0;
					foreach (StatusEffect statusEffect in db.m_StatusEffects)
					{
						if (!DumpManager._cancelRequested)
						{
							if ((Object)(object)statusEffect != (Object)null)
							{
								JObject val4 = new JObject();
								val4["_Key"] = JToken.op_Implicit(((Object)statusEffect).name);
								val4["_Source"] = JToken.op_Implicit("StatusEffects");
								val4["_displayName"] = JToken.op_Implicit(Loc.Resolve(statusEffect.m_name));
								val4["_class"] = JToken.op_Implicit(((object)statusEffect).GetType().Name);
								Walker.Walk(statusEffect, "", val4);
								writeObj(val4);
							}
							int num = n + 1;
							n = num;
							if (num % 10 == 0)
							{
								yield return null;
							}
							continue;
						}
						yield break;
					}
				}
			}
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null && ZNetScene.instance.m_prefabs.Count > 0)
			{
				Assembly valheim = typeof(ZNetScene).Assembly;
				n = 0;
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if (DumpManager._cancelRequested)
					{
						yield break;
					}
					if ((Object)(object)prefab != (Object)null)
					{
						JObject val5 = new JObject();
						val5["_Key"] = JToken.op_Implicit(((Object)prefab).name);
						val5["_Source"] = JToken.op_Implicit("Prefabs");
						Component[] array = null;
						try
						{
							array = prefab.GetComponents<Component>();
						}
						catch
						{
						}
						if (array != null)
						{
							val5["_components"] = JToken.op_Implicit(string.Join("|", from c in array
								where (Object)(object)c != (Object)null
								select ((object)c).GetType().Name));
							List<string> list = new List<string>();
							int childCount = prefab.transform.childCount;
							for (int num2 = 0; num2 < childCount && num2 < 32; num2++)
							{
								list.Add(((Object)prefab.transform.GetChild(num2)).name);
							}
							if (list.Count > 0)
							{
								val5["_children"] = JToken.op_Implicit(string.Join("|", list));
							}
							Component[] array2 = array;
							foreach (Component val6 in array2)
							{
								if (!((Object)(object)val6 == (Object)null))
								{
									Type type = ((object)val6).GetType();
									if (!(type.Assembly != valheim))
									{
										Walker.Walk(val6, type.Name + ".", val5);
									}
								}
							}
						}
						writeObj(val5);
					}
					int num = n + 1;
					n = num;
					if (num % 10 == 0)
					{
						yield return null;
					}
				}
			}
			if (!((Object)(object)ZoneSystem.instance != (Object)null))
			{
				yield break;
			}
			if (ZoneSystem.instance.m_vegetation != null && ZoneSystem.instance.m_vegetation.Count > 0)
			{
				n = 0;
				foreach (ZoneVegetation item2 in ZoneSystem.instance.m_vegetation)
				{
					if (!DumpManager._cancelRequested)
					{
						if (item2 != null)
						{
							JObject val7 = new JObject();
							val7["_Key"] = JToken.op_Implicit(Walker.NameOf(item2, "m_name", "m_prefab"));
							val7["_Source"] = JToken.op_Implicit("Vegetation");
							Walker.Walk(item2, "", val7);
							writeObj(val7);
						}
						int num = n + 1;
						n = num;
						if (num % 10 == 0)
						{
							yield return null;
						}
						continue;
					}
					yield break;
				}
			}
			if (ZoneSystem.instance.m_locations == null || ZoneSystem.instance.m_locations.Count <= 0)
			{
				yield break;
			}
			n = 0;
			foreach (ZoneLocation location in ZoneSystem.instance.m_locations)
			{
				if (!DumpManager._cancelRequested)
				{
					if (location != null)
					{
						JObject val8 = new JObject();
						val8["_Key"] = JToken.op_Implicit(Walker.NameOf(location, "m_prefabName", "m_prefab"));
						val8["_Source"] = JToken.op_Implicit("Locations");
						Walker.Walk(location, "", val8);
						writeObj(val8);
					}
					int num = n + 1;
					n = num;
					if (num % 10 == 0)
					{
						yield return null;
					}
					continue;
				}
				yield break;
			}
			void writeObj(JObject val9)
			{
				if (minifiedJsonl)
				{
					writer.WriteLine(((JToken)val9).ToString((Formatting)0, Array.Empty<JsonConverter>()));
				}
				else
				{
					if (!isFirst)
					{
						writer.Write(",\n");
					}
					writer.Write(((JToken)val9).ToString((Formatting)1, Array.Empty<JsonConverter>()));
					isFirst = false;
				}
			}
		}
	}
}
namespace WubarrksEye.Core.Commands
{
	public class CoroutineRunner : MonoBehaviour
	{
		private static CoroutineRunner _instance;

		[RuntimeInitializeOnLoadMethod]
		private static void Init()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (!((Object)_instance != (Object)null))
			{
				GameObject val = new GameObject("Wubarrk_CoroutineRunner");
				Object.DontDestroyOnLoad((Object)val);
				_instance = val.AddComponent<CoroutineRunner>();
			}
		}

		public static void Run(IEnumerator routine)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)_instance == (Object)null)
			{
				Init();
			}
			((MonoBehaviour)_instance).StartCoroutine(routine);
		}
	}
	public static class DumpManager
	{
		public struct DumpOptions
		{
			public bool DumpAgentML;

			public bool DumpAPI;

			public bool DumpPrefabs;

			public bool DumpScene;

			public bool DumpZDOs;

			public bool DumpObjectDB;

			public bool DumpValues;

			public bool DumpCallGraph;

			public bool RunHuginnsReport;

			public bool HuginnsReportMLFormat;
		}

		private class ApiExtractor : IDataExtractor
		{
			public string ExtractorName => "API Reflection";

			public string OutputFileName => "API_Dump.json";

			public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
			{
				return Extract(writer, minifiedJsonl: false);
			}

			public IEnumerator ExtractDataToZip(StreamWriter writer)
			{
				return Extract(writer, minifiedJsonl: true);
			}

			private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl)
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				List<Type> allTypes = new List<Type>();
				Assembly[] array = assemblies;
				foreach (Assembly assembly in array)
				{
					try
					{
						allTypes.AddRange(assembly.GetTypes());
					}
					catch
					{
					}
				}
				int totalTypes = allTypes.Count;
				int batchSize = 50;
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_32GB)
				{
					batchSize = 200;
				}
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_64GB_Plus)
				{
					batchSize = 1000;
				}
				bool isFirst = true;
				for (int j = 0; j < totalTypes; j += batchSize)
				{
					if (_cancelRequested)
					{
						break;
					}
					List<Type> chunk = allTypes.Skip(j).Take(batchSize).ToList();
					ConcurrentQueue<JObject> results = new ConcurrentQueue<JObject>();
					Task.Run(delegate
					{
						Parallel.ForEach(chunk, new ParallelOptions
						{
							MaxDegreeOfParallelism = 2
						}, delegate(Type t)
						{
							try
							{
								results.Enqueue(DumpTypeInfo(t));
							}
							catch
							{
							}
						});
					}).Wait();
					foreach (JObject item in results)
					{
						if (minifiedJsonl)
						{
							writer.WriteLine(((JToken)item).ToString((Formatting)0, Array.Empty<JsonConverter>()));
							continue;
						}
						if (!isFirst)
						{
							writer.Write(",\n");
						}
						writer.Write(((JToken)item).ToString((Formatting)1, Array.Empty<JsonConverter>()));
						isFirst = false;
					}
					_progress = (float)j / (float)totalTypes * 100f;
					yield return null;
				}
			}

			private JObject DumpTypeInfo(Type t)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Expected O, but got Unknown
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Expected O, but got Unknown
				JObject val = new JObject();
				if (t == null)
				{
					return val;
				}
				val["Type"] = JToken.op_Implicit("API_Type");
				val["FullName"] = JToken.op_Implicit(t.FullName);
				val["Namespace"] = JToken.op_Implicit(t.Namespace);
				val["Kind"] = JToken.op_Implicit(t.IsInterface ? "interface" : (t.IsEnum ? "enum" : (t.IsValueType ? "struct" : "class")));
				val["BaseType"] = JToken.op_Implicit(t.BaseType?.FullName);
				MethodInfo[] methods = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (methods.Length != 0)
				{
					JArray val2 = new JArray();
					MethodInfo[] array = methods;
					foreach (MethodInfo methodInfo in array)
					{
						JObject val3 = new JObject();
						val3["Name"] = JToken.op_Implicit(methodInfo.Name);
						val3["ReturnType"] = JToken.op_Implicit(methodInfo.ReturnType.FullName);
						val2.Add((JToken)(object)val3);
					}
					val["Methods"] = (JToken)(object)val2;
				}
				return val;
			}
		}

		private class PrefabExtractor : IDataExtractor
		{
			public string ExtractorName => "Prefabs";

			public string OutputFileName => "Prefabs_Dump.json";

			public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
			{
				return Extract(writer, minifiedJsonl: false);
			}

			public IEnumerator ExtractDataToZip(StreamWriter writer)
			{
				return Extract(writer, minifiedJsonl: true);
			}

			private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl)
			{
				if ((Object)(object)ZNetScene.instance == (Object)null)
				{
					yield break;
				}
				List<GameObject> prefabs = ZNetScene.instance.m_prefabs;
				int total = prefabs.Count;
				int num = 1;
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_32GB)
				{
					num = 3;
				}
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_64GB_Plus)
				{
					num = 10;
				}
				int batchSize = WubarrkConfig.BurstObjectsPerFrame.Value * num;
				if (batchSize <= 0)
				{
					batchSize = 10;
				}
				bool isFirst = true;
				for (int i = 0; i < total; i++)
				{
					if (_cancelRequested)
					{
						break;
					}
					GameObject val = prefabs[i];
					if ((Object)(object)val != (Object)null)
					{
						JObject val2 = DumpGameObjectData(val);
						if (minifiedJsonl)
						{
							writer.WriteLine(((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>()));
						}
						else
						{
							if (!isFirst)
							{
								writer.Write(",\n");
							}
							writer.Write(((JToken)val2).ToString((Formatting)1, Array.Empty<JsonConverter>()));
							isFirst = false;
						}
					}
					if (i % batchSize == 0)
					{
						_progress = (float)i / (float)total * 100f;
						yield return null;
					}
				}
			}
		}

		private class SceneExtractor : IDataExtractor
		{
			public string ExtractorName => "Scene Objects";

			public string OutputFileName => "Scene_Dump.json";

			public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
			{
				return Extract(writer, minifiedJsonl: false);
			}

			public IEnumerator ExtractDataToZip(StreamWriter writer)
			{
				return Extract(writer, minifiedJsonl: true);
			}

			private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl)
			{
				Scene activeScene = SceneManager.GetActiveScene();
				GameObject[] rootObjects = (GameObject[])(((Scene)(ref activeScene)).IsValid() ? ((Array)((Scene)(ref activeScene)).GetRootGameObjects()) : ((Array)new GameObject[0]));
				int num = 1;
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_32GB)
				{
					num = 3;
				}
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_64GB_Plus)
				{
					num = 10;
				}
				int batchSize = WubarrkConfig.BurstObjectsPerFrame.Value * num;
				if (batchSize <= 0)
				{
					batchSize = 10;
				}
				bool isFirst = true;
				int count = 0;
				GameObject[] array = rootObjects;
				foreach (GameObject val in array)
				{
					if (_cancelRequested)
					{
						break;
					}
					if ((Object)(object)val != (Object)null)
					{
						JObject val2 = DumpGameObjectData(val);
						if (minifiedJsonl)
						{
							writer.WriteLine(((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>()));
						}
						else
						{
							if (!isFirst)
							{
								writer.Write(",\n");
							}
							writer.Write(((JToken)val2).ToString((Formatting)1, Array.Empty<JsonConverter>()));
							isFirst = false;
						}
					}
					count++;
					if (count % batchSize == 0)
					{
						_progress = (float)count / (float)rootObjects.Length * 100f;
						yield return null;
					}
				}
			}
		}

		private class ZdoExtractor : IDataExtractor
		{
			public string ExtractorName => "ZDO State";

			public string OutputFileName => "ZDO_Dump.json";

			public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
			{
				return Extract(writer, minifiedJsonl: false);
			}

			public IEnumerator ExtractDataToZip(StreamWriter writer)
			{
				return Extract(writer, minifiedJsonl: true);
			}

			private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl)
			{
				if (ZDOMan.instance == null)
				{
					yield break;
				}
				List<ZDO> zdos = ZDOMan.instance.m_objectsByID.Values.ToList();
				int total = zdos.Count;
				int num = 1;
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_32GB)
				{
					num = 3;
				}
				if (WubarrkConfig.SystemMemoryProfile.Value == WubarrkConfig.RamProfile.Rig_64GB_Plus)
				{
					num = 10;
				}
				int batchSize = WubarrkConfig.BurstObjectsPerFrame.Value * 5 * num;
				if (batchSize <= 0)
				{
					batchSize = 50;
				}
				bool isFirst = true;
				for (int i = 0; i < total; i++)
				{
					if (_cancelRequested)
					{
						break;
					}
					ZDO val = zdos[i];
					if (val != null)
					{
						JObject val2 = new JObject();
						val2["Type"] = JToken.op_Implicit("ZDO");
						val2["UID"] = JToken.op_Implicit(((object)Unsafe.As<ZDOID, ZDOID>(ref val.m_uid)/*cast due to .constrained prefix*/).ToString());
						try
						{
							val2["Owner"] = JToken.op_Implicit(val.GetOwner());
						}
						catch
						{
						}
						val2["Prefab"] = JToken.op_Implicit(val.GetPrefab());
						val2["Position"] = JToken.op_Implicit(((object)val.GetPosition()/*cast due to .constrained prefix*/).ToString());
						if (minifiedJsonl)
						{
							writer.WriteLine(((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>()));
						}
						else
						{
							if (!isFirst)
							{
								writer.Write(",\n");
							}
							writer.Write(((JToken)val2).ToString((Formatting)1, Array.Empty<JsonConverter>()));
							isFirst = false;
						}
					}
					if (i % batchSize == 0)
					{
						_progress = (float)i / (float)total * 100f;
						yield return null;
					}
				}
			}
		}

		private class ObjectDbExtractor : IDataExtractor
		{
			public string ExtractorName => "ObjectDB";

			public string OutputFileName => "ObjectDB_Dump.json";

			public IEnumerator ExtractData(StreamWriter writer, int maxBytes)
			{
				return Extract(writer, minifiedJsonl: false);
			}

			public IEnumerator ExtractDataToZip(StreamWriter writer)
			{
				return Extract(writer, minifiedJsonl: true);
			}

			private IEnumerator Extract(StreamWriter writer, bool minifiedJsonl)
			{
				if ((Object)(object)ObjectDB.instance == (Object)null)
				{
					yield break;
				}
				bool isFirst = true;
				List<GameObject> items = ObjectDB.instance.m_items;
				int count = 0;
				foreach (GameObject item in items)
				{
					if (_cancelRequested)
					{
						break;
					}
					if ((Object)(object)item != (Object)null)
					{
						JObject val = DumpGameObjectData(item);
						if (minifiedJsonl)
						{
							writer.WriteLine(((JToken)val).ToString((Formatting)0, Array.Empty<JsonConverter>()));
						}
						else
						{
							if (!isFirst)
							{
								writer.Write(",\n");
							}
							writer.Write(((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>()));
							isFirst = false;
						}
					}
					count++;
					if (count % 10 == 0)
					{
						yield return null;
					}
				}
			}
		}

		private static bool _isRunning;

		internal static bool _cancelRequested;

		internal static float _progress;

		private static float _overallProgress;

		private static string _currentPhase = "";

		public static bool IsRunning => _isRunning;

		public static float ProgressPercentage => _progress;

		public static float OverallProgress => _overallProgress;

		public static string CurrentPhase => _currentPhase;

		public static void Start(string dumpRoot, DumpOptions options)
		{
			if (!_isRunning)
			{
				_isRunning = true;
				_cancelRequested = false;
				_progress = 0f;
				_overallProgress = 0f;
				_currentPhase = "Initializing";
				Directory.CreateDirectory(dumpRoot);
				CoroutineRunner.Run(DumpRoutine(dumpRoot, options));
			}
		}

		public static void Cancel()
		{
			_cancelRequested = true;
		}

		private static IEnumerator DumpRoutine(string dumpRoot, DumpOptions options)
		{
			try
			{
				WubarrkLogger.Info("[Eye.Deep] Streaming Dump started in " + dumpRoot);
				int maxBytes = WubarrkConfig.DumpMaxFileSizeMB.Value * 1024 * 1024;
				if (maxBytes <= 0)
				{
					maxBytes = 1073741824;
				}
				List<IDataExtractor> activeExtractors = new List<IDataExtractor>();
				if (options.DumpAPI)
				{
					activeExtractors.Add(new ApiExtractor());
				}
				if (options.DumpPrefabs)
				{
					activeExtractors.Add(new PrefabExtractor());
				}
				if (options.DumpScene)
				{
					activeExtractors.Add(new SceneExtractor());
				}
				if (options.DumpZDOs)
				{
					activeExtractors.Add(new ZdoExtractor());
				}
				if (options.DumpObjectDB)
				{
					activeExtractors.Add(new ObjectDbExtractor());
				}
				if (options.DumpValues)
				{
					activeExtractors.Add(new ValueExtractor());
				}
				if (options.DumpCallGraph)
				{
					activeExtractors.Add(new CallGraphExtractor());
				}
				int passes = (options.DumpAgentML ? 1 : 0) + 1;
				int passIndex = 0;
				for (int i = 0; i < activeExtractors.Count; i++)
				{
					if (_cancelRequested)
					{
						break;
					}
					IDataExtractor extractor = activeExtractors[i];
					_currentPhase = "Standard: " + extractor.ExtractorName;
					_progress = 0f;
					string path = Path.Combine(dumpRoot, extractor.OutputFileName);
					using (StreamWriter writer = new StreamWriter(path, append: false, Encoding.UTF8))
					{
						writer.Write("[\n");
						IEnumerator extRoutine = null;
						try
						{
							extRoutine = extractor.ExtractData(writer, maxBytes);
						}
						catch (Exception arg)
						{
							WubarrkLogger.Error($"[Eye.Deep] {extractor.ExtractorName} failed to start: {arg}");
						}
						while (extRoutine != null)
						{
							bool flag;
							try
							{
								flag = extRoutine.MoveNext();
							}
							catch (Exception arg2)
							{
								WubarrkLogger.Error($"[Eye.Deep] {extractor.ExtractorName} aborted: {arg2}");
								break;
							}
							if (!flag)
							{
								break;
							}
							_overallProgress = ((float)passIndex * 100f + ((float)i * 100f + _progress) / (float)activeExtractors.Count) / (float)passes;
							yield return extRoutine.Current;
						}
						writer.Write("\n]");
					}
					WubarrkLogger.Info("[Eye.Deep] Wrote " + extractor.OutputFileName);
				}
				passIndex++;
				if (options.DumpAgentML && !_cancelRequested)
				{
					_currentPhase = "Building AI Agent ML Dump (.zip)";
					string path2 = Path.Combine(dumpRoot, "AgentML_Complete_Dump.zip");
					using FileStream fs = new FileStream(path2, FileMode.Create);
					using ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create);
					ZipArchiveEntry zipArchiveEntry = archive.CreateEntry("AgentML_Complete_Dump.jsonl", CompressionLevel.Optimal);
					using StreamWriter writer = new StreamWriter(zipArchiveEntry.Open());
					for (int i = 0; i < activeExtractors.Count; i++)
					{
						if (_cancelRequested)
						{
							break;
						}
						IDataExtractor extractor = activeExtractors[i];
						_currentPhase = "ML: " + extractor.ExtractorName;
						_progress = 0f;
						IEnumerator extRoutine = null;
						try
						{
							extRoutine = extractor.ExtractDataToZip(writer);
						}
						catch (Exception arg3)
						{
							WubarrkLogger.Error($"[Eye.Deep] {extractor.ExtractorName} (ML) failed to start: {arg3}");
						}
						while (extRoutine != null)
						{
							bool flag2;
							try
							{
								flag2 = extRoutine.MoveNext();
							}
							catch (Exception arg4)
							{
								WubarrkLogger.Error($"[Eye.Deep] {extractor.ExtractorName} (ML) aborted: {arg4}");
								break;
							}
							if (!flag2)
							{
								break;
							}
							_overallProgress = ((float)passIndex * 100f + ((float)i * 100f + _progress) / (float)activeExtractors.Count) / (float)passes;
							yield return extRoutine.Current;
						}
					}
				}
				if (options.RunHuginnsReport && !_cancelRequested)
				{
					_currentPhase = "Huginn's Report (Diffing)";
					_progress = 0f;
					_overallProgress = 99f;
					yield return HuginnsReport.RunDiff(dumpRoot, options);
				}
				_progress = 100f;
				_overallProgress = 100f;
				_currentPhase = (_cancelRequested ? "Cancelled" : "Complete");
				WubarrkLogger.Info(_cancelRequested ? "[Eye.Deep] Dump cancelled." : ("[Eye.Deep] Dump completed successfully. Output: " + dumpRoot));
			}
			finally
			{
				_isRunning = false;
			}
		}

		private static JObject DumpGameObjectData(GameObject go)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			JObject val = new JObject();
			val["Type"] = JToken.op_Implicit("GameObject");
			val["Name"] = JToken.op_Implicit(((Object)go).name);
			Component[] components = go.GetComponents<Component>();
			JArray val2 = new JArray();
			Component[] array = components;
			foreach (Component val3 in array)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					JObject val4 = new JObject();
					val4["ComponentType"] = JToken.op_Implicit(((object)val3).GetType().FullName);
					ZNetView val5 = (ZNetView)(object)((val3 is ZNetView) ? val3 : null);
					if ((Object)(object)val5 != (Object)null)
					{
						val4["PrefabHash"] = JToken.op_Implicit(val5.GetPrefabName().GetHashCode());
					}
					val2.Add((JToken)(object)val4);
				}
			}
			val["Components"] = (JToken)(object)val2;
			return val;
		}
	}
	public static class HuginnsReport
	{
		public static IEnumerator RunDiff(string currentDumpRoot, DumpManager.DumpOptions options)
		{
			WubarrkLogger.Info("[Huginn] Preparing to execute Huginn's Report (Diff-er)...");
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Paths.ConfigPath, "WubarrksEye_Dumps"));
			if (!directoryInfo.Exists)
			{
				yield break;
			}
			List<DirectoryInfo> list = (from d in directoryInfo.GetDirectories()
				where d.FullName != currentDumpRoot
				orderby d.CreationTime descending
				select d).ToList();
			string previousDumpRoot = null;
			foreach (DirectoryInfo item in list)
			{
				if (options.DumpAgentML)
				{
					if (File.Exists(Path.Combine(item.FullName, "AgentML_Complete_Dump.zip")))
					{