Decompiled source of GameObjectDump v1.0.3

Silksong.GameObjectDump.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using HutongGames.PlayMaker;
using Microsoft.CodeAnalysis;
using Silksong.GameObjectDump.Logging;
using Silksong.GameObjectDump.Logging.Loggables;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Silksong.GameObjectDump")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+336f5ce775bfabffccee166016e49a0a3e9c552c")]
[assembly: AssemblyProduct("Silksong.GameObjectDump")]
[assembly: AssemblyTitle("GameObjectDump")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/syyePhenomenol/Silksong.GameObjectDump")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace System.Runtime.CompilerServices
{
	internal static class IsExternalInit
	{
	}
}
namespace Silksong.GameObjectDump
{
	public static class GameObjectDump
	{
		public static void Dump(this GameObject? go, string? path = null, bool append = false, DumpOptions? dumpOptions = null)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			try
			{
				if (path == null)
				{
					path = Path.Combine(GetAssemblyPath(), ((Object)go).name + ".txt");
				}
			}
			catch (Exception ex)
			{
				GameObjectDumpPlugin.LogError("Failed to retrieve assembly or file path: " + ex.Message);
				return;
			}
			((IEnumerable<GameObject?>?)new <>z__ReadOnlySingleElementList<GameObject>(go)).Dump(path, append, dumpOptions);
		}

		public static void Dump(this Scene scene, string? path = null, bool append = false, DumpOptions? dumpOptions = null)
		{
			try
			{
				if (path == null)
				{
					path = Path.Combine(GetAssemblyPath(), ((Scene)(ref scene)).name + ".txt");
				}
			}
			catch (Exception ex)
			{
				GameObjectDumpPlugin.LogError("Failed to retrieve assembly or file path: " + ex.Message);
				return;
			}
			((IEnumerable<GameObject?>?)((Scene)(ref scene)).GetRootGameObjects()).Dump(path, append, dumpOptions);
		}

		public static void Dump(this IEnumerable<GameObject?>? gameObjects, string? path, bool append = false, DumpOptions? dumpOptions = null)
		{
			if (gameObjects == null)
			{
				return;
			}
			LogContext logContext = new LogContext(dumpOptions ?? new DumpOptions());
			try
			{
				logContext.RegisterCoreObjects(gameObjects);
			}
			catch (Exception ex)
			{
				GameObjectDumpPlugin.LogError("Failed to register core objects: " + ex.Message);
				return;
			}
			List<LogEdge> list = gameObjects.Select((GameObject go, int idx) => new LogEdge(go, idx.ToString())with
			{
				InCoreHierarchy = true
			}).ToList();
			try
			{
				foreach (LogEdge item in list)
				{
					item.Propagate(logContext);
				}
			}
			catch (Exception ex2)
			{
				GameObjectDumpPlugin.LogError("Failed to fill log nodes: " + ex2.Message);
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			try
			{
				foreach (LogEdge item2 in list)
				{
					if (!logContext.DumpOptions.OmitIfNotFull || logContext.IsCoreObject(item2.Object))
					{
						WriteEdge(stringBuilder, item2, 0, logContext);
					}
				}
			}
			catch (Exception ex3)
			{
				GameObjectDumpPlugin.LogError("Failed to build string: " + ex3.Message);
				return;
			}
			try
			{
				string text = Path.GetExtension(path).ToLowerInvariant();
				switch (text)
				{
				default:
					GameObjectDumpPlugin.LogError("Unsupported file type: " + text);
					break;
				case ".txt":
				case ".log":
				case ".json":
					if (!append)
					{
						File.Delete(path);
					}
					File.AppendAllText(path, stringBuilder.ToString());
					break;
				}
			}
			catch (Exception ex4)
			{
				GameObjectDumpPlugin.LogError("Failed to write to file: " + ex4.Message);
			}
		}

		public static void ClearReflectionCaches()
		{
			LoggableRegistry.ClearReflectionCaches();
		}

		private static string GetAssemblyPath()
		{
			string text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (string.IsNullOrEmpty(text))
			{
				text = Application.persistentDataPath;
			}
			return text;
		}

		private static void WriteEdge(StringBuilder sb, LogEdge edge, int indent, LogContext ctx)
		{
			if (edge.Node == null)
			{
				GameObjectDumpPlugin.LogWarning("Null node! " + edge.Header);
				return;
			}
			string text = new string(' ', indent * 2);
			string header = edge.Header;
			if (edge.Node is ValueLogNode valueLogNode)
			{
				header = ((!string.IsNullOrEmpty(header)) ? (header + ": ") : "");
				sb.AppendLine(text + header + valueLogNode.ConciseLog);
			}
			else
			{
				if (!(edge.Node is ReferenceLogNode referenceLogNode))
				{
					return;
				}
				bool flag = ctx.RegisterFinalId(referenceLogNode);
				bool flag2 = edge.InCoreHierarchy || (!ctx.IsCoreObject(edge.Object) && flag);
				int? id = referenceLogNode.Id;
				object obj;
				if (id.HasValue)
				{
					int valueOrDefault = id.GetValueOrDefault();
					obj = string.Format("[{0} {1}]", flag2 ? "ID" : "REF", valueOrDefault);
				}
				else
				{
					obj = null;
				}
				string item = (string)obj;
				if (flag2 && referenceLogNode.Children.Any())
				{
					header = JoinWithWhiteSpace(new List<string>(3) { edge.Header, referenceLogNode.ExtraHeader, item });
					header = ((!string.IsNullOrEmpty(header)) ? (header + ":") : "[missing header]:");
					sb.AppendLine(text + header);
					{
						foreach (LogEdge child in referenceLogNode.Children)
						{
							WriteEdge(sb, child, indent + 1, ctx);
						}
						return;
					}
				}
				header = JoinWithWhiteSpace(new List<string>(2) { header, item });
				header = ((!string.IsNullOrEmpty(header)) ? (header + ": ") : "");
				sb.AppendLine(text + header + referenceLogNode.ConciseLog);
			}
		}

		private static string JoinWithWhiteSpace(List<string?> strings)
		{
			return string.Join(" ", strings.Where((string s) => !string.IsNullOrEmpty(s)));
		}
	}
	[BepInPlugin("io.github.syyephenomenol.gameobjectdump", "GameObjectDump", "1.0.3")]
	public class GameObjectDumpPlugin : BaseUnityPlugin
	{
		public const string Id = "io.github.syyephenomenol.gameobjectdump";

		internal static GameObjectDumpPlugin? Instance { get; private set; }

		public static string Name => "GameObjectDump";

		public static string Version => "1.0.3";

		internal static void Log(string text)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)text);
			}
		}

		internal static void LogWarning(string text)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)text);
			}
		}

		internal static void LogError(string text)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				((BaseUnityPlugin)Instance).Logger.LogError((object)text);
			}
		}

		private void Awake()
		{
			Instance = this;
			LoggableRegistry.Initialize();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (io.github.syyephenomenol.gameobjectdump) has loaded!"));
		}
	}
	public static class TypeExtensions
	{
		public static string GetPrettyNameFromObject(this object obj)
		{
			return obj.GetType().GetPrettyNameFromType();
		}

		public static string GetPrettyNameFromType(this Type type)
		{
			if (type.IsGenericType)
			{
				string text = type.Name;
				int num = text.IndexOf('`');
				if (num > 0)
				{
					text = text.Substring(0, num);
				}
				IEnumerable<string> values = type.GetGenericArguments().Select(GetPrettyNameFromType);
				return text + "<" + string.Join(", ", values) + ">";
			}
			if (type.IsArray)
			{
				return type.GetElementType().GetPrettyNameFromType() + "[]";
			}
			Type underlyingType = Nullable.GetUnderlyingType(type);
			if ((object)underlyingType != null)
			{
				return underlyingType.GetPrettyNameFromType() + "?";
			}
			if ((object)type != null)
			{
				if (type == typeof(int))
				{
					return "int";
				}
				if (type == typeof(string))
				{
					return "string";
				}
				if (type == typeof(bool))
				{
					return "bool";
				}
				if (type == typeof(float))
				{
					return "float";
				}
				if (type == typeof(double))
				{
					return "double";
				}
				if (type == typeof(decimal))
				{
					return "decimal";
				}
				if (type == typeof(void))
				{
					return "void";
				}
			}
			return type.Name;
		}
	}
}
namespace Silksong.GameObjectDump.Logging
{
	public record DumpOptions
	{
		public Func<Component, bool> DumpFullComponent { get; init; } = (Component c) => true;


		public Func<FsmStateAction, bool> DumpFullFsmAction { get; init; } = (FsmStateAction a) => true;


		public bool DumpFullGameObjectChildren { get; init; } = true;


		public bool OmitIfNotFull { get; init; } = true;


		public Func<Type, bool> DumpReflectedType { get; init; } = (Type c) => true;


		public int LargeArrayThreshold { get; init; } = 100;


		public static DumpOptions MonoBehavioursOnly { get; } = new DumpOptions
		{
			DumpFullComponent = (Component c) => c is MonoBehaviour
		};


		public static DumpOptions FsmsOnly { get; } = new DumpOptions
		{
			DumpFullComponent = (Component c) => c is PlayMakerFSM
		};


		[CompilerGenerated]
		protected DumpOptions(DumpOptions original)
		{
			DumpFullComponent = original.DumpFullComponent;
			DumpFullFsmAction = original.DumpFullFsmAction;
			DumpFullGameObjectChildren = original.DumpFullGameObjectChildren;
			OmitIfNotFull = original.OmitIfNotFull;
			DumpReflectedType = original.DumpReflectedType;
			LargeArrayThreshold = original.LargeArrayThreshold;
		}

		public DumpOptions()
		{
		}
	}
	public class LogContext
	{
		[CompilerGenerated]
		private DumpOptions? <dumpOptions>P;

		private readonly HashSet<object> _coreObjects;

		private readonly Dictionary<object, ReferenceLogNode> _logNodeCache;

		private int _nextId;

		public DumpOptions DumpOptions => <dumpOptions>P ?? new DumpOptions();

		public LogContext(DumpOptions? dumpOptions = null)
		{
			<dumpOptions>P = dumpOptions;
			_coreObjects = new HashSet<object>();
			_logNodeCache = new Dictionary<object, ReferenceLogNode>(ReferenceComparer.Instance);
			base..ctor();
		}

		internal void CacheAndRegisterNode(object obj, ReferenceLogNode node)
		{
			_logNodeCache.Add(obj, node);
		}

		internal bool TryGetCachedNode(object obj, out ReferenceLogNode node)
		{
			if (!_logNodeCache.TryGetValue(obj, out node))
			{
				return false;
			}
			node.ApplyId = true;
			return true;
		}

		internal void RegisterCoreObjects(IEnumerable<GameObject?> gameObjects)
		{
			foreach (GameObject gameObject in gameObjects)
			{
				if ((Object)(object)gameObject != (Object)null && RegisterGameObject(gameObject))
				{
					_coreObjects.Add(gameObject);
				}
			}
		}

		internal bool IsCoreObject(object? obj)
		{
			if (obj != null)
			{
				return _coreObjects.Contains(obj);
			}
			return false;
		}

		internal bool RegisterFinalId(ReferenceLogNode node)
		{
			if (!node.ApplyId)
			{
				return true;
			}
			if (node.Id.HasValue)
			{
				return false;
			}
			node.Id = _nextId++;
			return true;
		}

		private bool RegisterGameObject(GameObject go)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			bool result = false;
			Component[] components = go.GetComponents<Component>();
			foreach (Component val in components)
			{
				if (!((Object)(object)val == (Object)null) && DumpOptions.DumpFullComponent(val))
				{
					PlayMakerFSM val2 = (PlayMakerFSM)(object)((val is PlayMakerFSM) ? val : null);
					if (val2 == null || RegisterFsm(val2))
					{
						_coreObjects.Add(val);
						result = true;
					}
				}
			}
			if (!DumpOptions.DumpFullGameObjectChildren)
			{
				return result;
			}
			foreach (Transform item in go.transform)
			{
				Transform val3 = item;
				if ((Object)(object)val3 != (Object)null && RegisterGameObject(((Component)val3).gameObject))
				{
					_coreObjects.Add(((Component)val3).gameObject);
					result = true;
				}
			}
			return result;
		}

		private bool RegisterFsm(PlayMakerFSM fsm)
		{
			if ((Object)(object)fsm == (Object)null)
			{
				return false;
			}
			bool result = false;
			FsmState[] fsmStates = fsm.FsmStates;
			foreach (FsmState val in fsmStates)
			{
				FsmStateAction[] actions = val.Actions;
				foreach (FsmStateAction val2 in actions)
				{
					if (DumpOptions.DumpFullFsmAction(val2))
					{
						_coreObjects.Add(val2);
						result = true;
					}
				}
				_coreObjects.Add(val);
			}
			return result;
		}
	}
	public sealed class ReferenceComparer : IEqualityComparer<object>
	{
		public static readonly ReferenceComparer Instance = new ReferenceComparer();

		private ReferenceComparer()
		{
		}

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

		public int GetHashCode(object obj)
		{
			return RuntimeHelpers.GetHashCode(obj);
		}
	}
	public sealed record LogEdge
	{
		public object? Object { get; set; }

		public string? Header { get; set; }

		public LogNode? Node { get; set; }

		internal bool InCoreHierarchy { get; set; }

		public LogEdge()
		{
		}

		public LogEdge(object? obj, string? header)
		{
			Object = obj;
			Header = header;
			if (Object == null)
			{
				Node = new ValueLogNode
				{
					ConciseLog = "[null]"
				};
				return;
			}
			if (Object is string conciseLog)
			{
				Node = new ValueLogNode
				{
					ConciseLog = conciseLog
				};
				return;
			}
			object? @object = Object;
			Object val = (Object)((@object is Object) ? @object : null);
			if (val != null && val == (Object)null)
			{
				Node = new ValueLogNode
				{
					ConciseLog = "[null Unity object] (" + Object.GetPrettyNameFromObject() + ")"
				};
			}
		}

		public static LogEdge GetEdgeRef(object parent, string memberName, string? headerOverride = null)
		{
			string header = headerOverride ?? memberName;
			Type type = parent.GetType();
			MemberInfo memberCached = LoggableRegistry.GetMemberCached(type, memberName);
			if ((object)memberCached == null)
			{
				return new LogEdge("[Could not find member name " + memberName + " in " + type.GetPrettyNameFromType() + "]", header);
			}
			return GetEdgeRef(parent, memberCached, headerOverride);
		}

		public static LogEdge GetEdgeRef(object parent, MemberInfo member, string? headerOverride = null)
		{
			string header = headerOverride ?? member.Name;
			object obj2;
			try
			{
				object obj = ((member is FieldInfo fieldInfo) ? fieldInfo.GetValue(parent) : ((!(member is PropertyInfo propertyInfo)) ? null : propertyInfo.GetValue(parent)));
				obj2 = obj;
			}
			catch
			{
				return new LogEdge("[Failed to get member " + member.Name + " in " + parent.GetPrettyNameFromObject() + "]", header);
			}
			return new LogEdge(obj2, header);
		}

		internal void Propagate(LogContext ctx)
		{
			if (Node is ReferenceLogNode referenceLogNode)
			{
				{
					foreach (LogEdge child in referenceLogNode.Children)
					{
						if (!(child.Node is ValueLogNode))
						{
							child.Propagate(ctx);
						}
					}
					return;
				}
			}
			if (Node is ValueLogNode)
			{
				GameObjectDumpPlugin.LogWarning("A ValueLogNode was enqueued: " + Header);
				return;
			}
			if (Object == null)
			{
				GameObjectDumpPlugin.Log("Object is null: " + Header);
				return;
			}
			if (ctx.TryGetCachedNode(Object, out ReferenceLogNode node))
			{
				Node = node;
				return;
			}
			Node = LoggableRegistry.ToLog(Object, ctx);
			if (!(Node is ReferenceLogNode referenceLogNode2))
			{
				return;
			}
			ctx.CacheAndRegisterNode(Object, referenceLogNode2);
			foreach (LogEdge child2 in referenceLogNode2.Children)
			{
				if (!(child2.Node is ValueLogNode))
				{
					child2.Propagate(ctx);
				}
			}
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("Object = ");
			builder.Append(Object);
			builder.Append(", Header = ");
			builder.Append((object?)Header);
			builder.Append(", Node = ");
			builder.Append(Node);
			return true;
		}
	}
	public abstract class LogNode
	{
		public string? ConciseLog { get; set; }
	}
	public sealed class ValueLogNode : LogNode
	{
	}
	public sealed class ReferenceLogNode : LogNode
	{
		public List<LogEdge> Children = new List<LogEdge>();

		public string? ExtraHeader { get; set; }

		public bool ApplyId { get; set; }

		public int? Id { get; set; }
	}
	public class PriorityQueue<T>
	{
		private readonly List<(T Item, int Priority)> _heap = new List<(T, int)>();

		public int Count => _heap.Count;

		public bool IsEmpty => _heap.Count == 0;

		public void Enqueue(T item, int priority)
		{
			_heap.Add((item, priority));
			HeapifyUp(_heap.Count - 1);
		}

		public T Dequeue()
		{
			if (_heap.Count == 0)
			{
				throw new InvalidOperationException("Queue is empty");
			}
			T item = _heap[0].Item;
			List<(T Item, int Priority)> heap = _heap;
			List<(T Item, int Priority)> heap2 = _heap;
			heap[0] = heap2[heap2.Count - 1];
			_heap.RemoveAt(_heap.Count - 1);
			if (_heap.Count > 0)
			{
				HeapifyDown(0);
			}
			return item;
		}

		public (T Item, int Priority) Peek()
		{
			if (_heap.Count == 0)
			{
				throw new InvalidOperationException("Queue is empty");
			}
			return _heap[0];
		}

		private void HeapifyUp(int i)
		{
			while (i > 0)
			{
				int num = (i - 1) / 2;
				if (_heap[i].Priority < _heap[num].Priority)
				{
					List<(T, int)> heap = _heap;
					int index = i;
					List<(T Item, int Priority)> heap2 = _heap;
					int index2 = num;
					(T, int) value = _heap[num];
					(T, int) value2 = _heap[i];
					heap[index] = value;
					heap2[index2] = value2;
					i = num;
					continue;
				}
				break;
			}
		}

		private void HeapifyDown(int i)
		{
			int num = _heap.Count - 1;
			while (true)
			{
				int num2 = 2 * i + 1;
				int num3 = 2 * i + 2;
				int num4 = i;
				if (num2 <= num && _heap[num2].Priority < _heap[num4].Priority)
				{
					num4 = num2;
				}
				if (num3 <= num && _heap[num3].Priority < _heap[num4].Priority)
				{
					num4 = num3;
				}
				if (num4 != i)
				{
					List<(T, int)> heap = _heap;
					int index = i;
					List<(T Item, int Priority)> heap2 = _heap;
					int index2 = num4;
					(T, int) value = _heap[num4];
					(T, int) value2 = _heap[i];
					heap[index] = value;
					heap2[index2] = value2;
					i = num4;
					continue;
				}
				break;
			}
		}
	}
}
namespace Silksong.GameObjectDump.Logging.Loggables
{
	public class LoggableBool : Loggable<ValueLogNode, bool>
	{
		public override void Fill(ValueLogNode node, bool obj, LogContext ctx)
		{
			node.ConciseLog = obj.ToString();
		}
	}
	public class LoggableString : Loggable<ValueLogNode, string>
	{
		public override void Fill(ValueLogNode node, string obj, LogContext ctx)
		{
			node.ConciseLog = obj;
		}
	}
	public class LoggableEnum : Loggable<ValueLogNode, Enum>
	{
		public override void Fill(ValueLogNode node, Enum obj, LogContext ctx)
		{
			node.ConciseLog = Convert.ToString(obj);
		}
	}
	public class LoggableIFormattable : Loggable<ValueLogNode, IFormattable>
	{
		public override void Fill(ValueLogNode node, IFormattable obj, LogContext ctx)
		{
			node.ConciseLog = Convert.ToString(obj)?.Replace("\n", ", ") ?? "[null]";
		}
	}
	public class LoggableIEnumerable : Loggable<ReferenceLogNode, IEnumerable>
	{
		[CompilerGenerated]
		private sealed class <GetChildren>d__1 : IEnumerable<LogEdge>, IEnumerable, IEnumerator<LogEdge>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private LogEdge <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable ie;

			public IEnumerable <>3__ie;

			private int <idx>5__2;

			private IEnumerator <>7__wrap2;

			LogEdge IEnumerator<LogEdge>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetChildren>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<idx>5__2 = 0;
						<>7__wrap2 = ie.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<idx>5__2++;
						break;
					}
					if (<>7__wrap2.MoveNext())
					{
						object current = <>7__wrap2.Current;
						<>2__current = new LogEdge(current, <idx>5__2.ToString());
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap2 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<LogEdge> IEnumerable<LogEdge>.GetEnumerator()
			{
				<GetChildren>d__1 <GetChildren>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetChildren>d__ = this;
				}
				else
				{
					<GetChildren>d__ = new <GetChildren>d__1(0);
				}
				<GetChildren>d__.ie = <>3__ie;
				return <GetChildren>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<LogEdge>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, IEnumerable obj, LogContext ctx)
		{
			if (!obj.GetEnumerator().MoveNext())
			{
				node.ConciseLog = "[empty " + obj.GetPrettyNameFromObject() + "]";
				return;
			}
			List<LogEdge> list = GetChildren(obj).ToList();
			node.ConciseLog = $"[{list.Count} objects in {obj.GetPrettyNameFromObject()}]";
			if (list.Count <= ctx.DumpOptions.LargeArrayThreshold)
			{
				node.Children.AddRange(list);
			}
		}

		[IteratorStateMachine(typeof(<GetChildren>d__1))]
		public static IEnumerable<LogEdge> GetChildren(IEnumerable ie)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetChildren>d__1(-2)
			{
				<>3__ie = ie
			};
		}
	}
	public class DefaultForeignLoggable : DefaultLoggable
	{
		[CompilerGenerated]
		private sealed class <GetAllMembers>d__2 : IEnumerable<(Type, LogEdge)>, IEnumerable, IEnumerator<(Type, LogEdge)>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private (Type, LogEdge) <>2__current;

			private int <>l__initialThreadId;

			private object parent;

			public object <>3__parent;

			private MemberInfo[] <>7__wrap1;

			private int <>7__wrap2;

			(Type, LogEdge) IEnumerator<(Type, LogEdge)>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAllMembers>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>7__wrap1 = LoggableRegistry.GetAllMembersCached(parent.GetType());
					<>7__wrap2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<>7__wrap2++;
					break;
				}
				if (<>7__wrap2 < <>7__wrap1.Length)
				{
					MemberInfo memberInfo = <>7__wrap1[<>7__wrap2];
					Type type;
					if (!(memberInfo is FieldInfo fieldInfo))
					{
						if (!(memberInfo is PropertyInfo propertyInfo))
						{
							throw new NotImplementedException();
						}
						type = propertyInfo.PropertyType;
					}
					else
					{
						type = fieldInfo.FieldType;
					}
					Type item = type;
					<>2__current = (item, LogEdge.GetEdgeRef(parent, memberInfo));
					<>1__state = 1;
					return true;
				}
				<>7__wrap1 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<(Type, LogEdge)> IEnumerable<(Type, LogEdge)>.GetEnumerator()
			{
				<GetAllMembers>d__2 <GetAllMembers>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetAllMembers>d__ = this;
				}
				else
				{
					<GetAllMembers>d__ = new <GetAllMembers>d__2(0);
				}
				<GetAllMembers>d__.parent = <>3__parent;
				return <GetAllMembers>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<(Type, LogEdge)>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, object obj, LogContext ctx)
		{
			FillAllMembers(node, obj, ctx);
		}

		public static void FillAllMembers(ReferenceLogNode node, object obj, LogContext ctx)
		{
			LogContext ctx2 = ctx;
			string text = "[foreign] " + obj.GetPrettyNameFromObject();
			if (node.ConciseLog == null)
			{
				string text3 = (node.ConciseLog = text);
			}
			List<(Type, LogEdge)> source = GetAllMembers(obj).ToList();
			node.Children.AddRange(from m in source
				where DefaultLoggable.ShouldDumpReflectedMember(m.type, ctx2)
				select m.edge);
			node.ExtraHeader = "--- " + text;
		}

		[IteratorStateMachine(typeof(<GetAllMembers>d__2))]
		public static IEnumerable<(Type, LogEdge)> GetAllMembers(object parent)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAllMembers>d__2(-2)
			{
				<>3__parent = parent
			};
		}
	}
	public class DefaultLoggable : Loggable<ReferenceLogNode, object>
	{
		[CompilerGenerated]
		private sealed class <GetSerializableFields>d__4 : IEnumerable<(Type, LogEdge)>, IEnumerable, IEnumerator<(Type, LogEdge)>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private (Type, LogEdge) <>2__current;

			private int <>l__initialThreadId;

			private object parent;

			public object <>3__parent;

			private ICollection<string> ignoreFields;

			public ICollection<string> <>3__ignoreFields;

			private FieldInfo[] <>7__wrap1;

			private int <>7__wrap2;

			(Type, LogEdge) IEnumerator<(Type, LogEdge)>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetSerializableFields>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_008c;
				}
				<>1__state = -1;
				<>7__wrap1 = LoggableRegistry.GetSerializableFieldsCached(parent.GetType());
				<>7__wrap2 = 0;
				goto IL_009a;
				IL_008c:
				<>7__wrap2++;
				goto IL_009a;
				IL_009a:
				if (<>7__wrap2 < <>7__wrap1.Length)
				{
					FieldInfo fieldInfo = <>7__wrap1[<>7__wrap2];
					ICollection<string> collection = ignoreFields;
					if (collection == null || !collection.Contains(fieldInfo.Name))
					{
						<>2__current = (fieldInfo.FieldType, LogEdge.GetEdgeRef(parent, fieldInfo));
						<>1__state = 1;
						return true;
					}
					goto IL_008c;
				}
				<>7__wrap1 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<(Type, LogEdge)> IEnumerable<(Type, LogEdge)>.GetEnumerator()
			{
				<GetSerializableFields>d__4 <GetSerializableFields>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetSerializableFields>d__ = this;
				}
				else
				{
					<GetSerializableFields>d__ = new <GetSerializableFields>d__4(0);
				}
				<GetSerializableFields>d__.parent = <>3__parent;
				<GetSerializableFields>d__.ignoreFields = <>3__ignoreFields;
				return <GetSerializableFields>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<(Type, LogEdge)>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetSerializableProperties>d__5 : IEnumerable<(Type, LogEdge)>, IEnumerable, IEnumerator<(Type, LogEdge)>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private (Type, LogEdge) <>2__current;

			private int <>l__initialThreadId;

			private object parent;

			public object <>3__parent;

			private ICollection<string> ignoreProperties;

			public ICollection<string> <>3__ignoreProperties;

			private PropertyInfo[] <>7__wrap1;

			private int <>7__wrap2;

			(Type, LogEdge) IEnumerator<(Type, LogEdge)>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetSerializableProperties>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_008c;
				}
				<>1__state = -1;
				<>7__wrap1 = LoggableRegistry.GetGetPropertiesCached(parent.GetType());
				<>7__wrap2 = 0;
				goto IL_009a;
				IL_008c:
				<>7__wrap2++;
				goto IL_009a;
				IL_009a:
				if (<>7__wrap2 < <>7__wrap1.Length)
				{
					PropertyInfo propertyInfo = <>7__wrap1[<>7__wrap2];
					ICollection<string> collection = ignoreProperties;
					if (collection == null || !collection.Contains(propertyInfo.Name))
					{
						<>2__current = (propertyInfo.PropertyType, LogEdge.GetEdgeRef(parent, propertyInfo));
						<>1__state = 1;
						return true;
					}
					goto IL_008c;
				}
				<>7__wrap1 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<(Type, LogEdge)> IEnumerable<(Type, LogEdge)>.GetEnumerator()
			{
				<GetSerializableProperties>d__5 <GetSerializableProperties>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetSerializableProperties>d__ = this;
				}
				else
				{
					<GetSerializableProperties>d__ = new <GetSerializableProperties>d__5(0);
				}
				<GetSerializableProperties>d__.parent = <>3__parent;
				<GetSerializableProperties>d__.ignoreProperties = <>3__ignoreProperties;
				return <GetSerializableProperties>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<(Type, LogEdge)>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, object obj, LogContext ctx)
		{
			FillBaseGameType(node, obj, ctx);
		}

		public static void FillBaseGameType(ReferenceLogNode node, object obj, LogContext ctx, ICollection<string>? ignoreMembers = null)
		{
			string name = obj.GetType().Assembly.GetName().Name;
			if (!name.StartsWith("Unity") && !name.StartsWith("Assembly-CSharp") && !name.StartsWith("TeamCherry") && !name.StartsWith("HutongGames") && !name.StartsWith("PlayMaker") && !name.StartsWith("InControl") && !name.StartsWith("QuestPlayMakerActions") && !name.StartsWith("StateMachineBehaviours"))
			{
				node.ConciseLog = "[unhandled type " + obj.GetPrettyNameFromObject() + "]";
			}
			else if (!FillFields(node, obj, ctx, ignoreMembers))
			{
				FillProperties(node, obj, ctx, ignoreMembers);
			}
		}

		public static bool FillFields(ReferenceLogNode node, object obj, LogContext ctx, ICollection<string>? ignoreFields = null)
		{
			LogContext ctx2 = ctx;
			List<(Type, LogEdge)> list = GetSerializableFields(obj, ignoreFields).ToList();
			if (list.Count == 0)
			{
				if (node.ConciseLog != null)
				{
					node.ConciseLog += " [no auto-fields]";
				}
				else
				{
					node.ConciseLog = "[no auto-fields in " + obj.GetPrettyNameFromObject() + "]";
				}
				return false;
			}
			if (node.ConciseLog == null)
			{
				string text = (node.ConciseLog = obj.GetPrettyNameFromObject());
			}
			node.Children.AddRange(from f in list
				where ShouldDumpReflectedMember(f.type, ctx2)
				select f.edge);
			return true;
		}

		public static bool FillProperties(ReferenceLogNode node, object obj, LogContext ctx, ICollection<string>? ignoreProperties = null)
		{
			LogContext ctx2 = ctx;
			List<(Type, LogEdge)> list = GetSerializableProperties(obj, ignoreProperties).ToList();
			if (list.Count == 0)
			{
				if (node.ConciseLog != null)
				{
					node.ConciseLog += " [no auto-properties]";
				}
				else
				{
					node.ConciseLog = "[no auto-properties in " + obj.GetPrettyNameFromObject() + "]";
				}
				return false;
			}
			node.ConciseLog = obj.GetPrettyNameFromObject();
			node.Children.AddRange(from p in list
				where ShouldDumpReflectedMember(p.type, ctx2)
				select p.edge);
			return true;
		}

		[IteratorStateMachine(typeof(<GetSerializableFields>d__4))]
		public static IEnumerable<(Type, LogEdge)> GetSerializableFields(object parent, ICollection<string>? ignoreFields = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetSerializableFields>d__4(-2)
			{
				<>3__parent = parent,
				<>3__ignoreFields = ignoreFields
			};
		}

		[IteratorStateMachine(typeof(<GetSerializableProperties>d__5))]
		public static IEnumerable<(Type, LogEdge)> GetSerializableProperties(object parent, ICollection<string>? ignoreProperties = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetSerializableProperties>d__5(-2)
			{
				<>3__parent = parent,
				<>3__ignoreProperties = ignoreProperties
			};
		}

		public static bool ShouldDumpReflectedMember(Type type, LogContext ctx)
		{
			try
			{
				return ctx.DumpOptions.DumpReflectedType(type);
			}
			catch (Exception ex)
			{
				GameObjectDumpPlugin.LogError("Failed to invoke DumpReflectedType: " + ex.Message);
			}
			return true;
		}
	}
	public class LoggablePlayMakerFSM : Loggable<ReferenceLogNode, PlayMakerFSM>
	{
		[CompilerGenerated]
		private sealed class <GetStateEdges>d__1 : IEnumerable<LogEdge>, IEnumerable, IEnumerator<LogEdge>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private LogEdge <>2__current;

			private int <>l__initialThreadId;

			private PlayMakerFSM fsm;

			public PlayMakerFSM <>3__fsm;

			private LogContext ctx;

			public LogContext <>3__ctx;

			private int <idx>5__2;

			private FsmState[] <>7__wrap2;

			private int <>7__wrap3;

			LogEdge IEnumerator<LogEdge>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetStateEdges>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0094;
				}
				<>1__state = -1;
				<idx>5__2 = 0;
				<>7__wrap2 = fsm.FsmStates;
				<>7__wrap3 = 0;
				goto IL_00b2;
				IL_0094:
				<idx>5__2++;
				<>7__wrap3++;
				goto IL_00b2;
				IL_00b2:
				if (<>7__wrap3 < <>7__wrap2.Length)
				{
					FsmState obj = <>7__wrap2[<>7__wrap3];
					if (!ctx.DumpOptions.OmitIfNotFull || ctx.IsCoreObject(obj))
					{
						<>2__current = new LogEdge(obj, <idx>5__2.ToString())
						{
							InCoreHierarchy = true
						};
						<>1__state = 1;
						return true;
					}
					goto IL_0094;
				}
				<>7__wrap2 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<LogEdge> IEnumerable<LogEdge>.GetEnumerator()
			{
				<GetStateEdges>d__1 <GetStateEdges>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetStateEdges>d__ = this;
				}
				else
				{
					<GetStateEdges>d__ = new <GetStateEdges>d__1(0);
				}
				<GetStateEdges>d__.fsm = <>3__fsm;
				<GetStateEdges>d__.ctx = <>3__ctx;
				return <GetStateEdges>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<LogEdge>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, PlayMakerFSM obj, LogContext ctx)
		{
			node.ConciseLog = obj.FsmName + " [" + obj.GetPrettyNameFromObject() + "]";
			if (ctx.IsCoreObject(obj))
			{
				node.Children.AddRange(new <>z__ReadOnlyArray<LogEdge>(new LogEdge[6]
				{
					LogEdge.GetEdgeRef(obj, "Active"),
					LogEdge.GetEdgeRef(obj, "ActiveStateName"),
					LogEdge.GetEdgeRef(obj, "UsesTemplate"),
					LogEdge.GetEdgeRef(obj, "FsmVariables"),
					LogEdge.GetEdgeRef(obj, "FsmEvents"),
					LogEdge.GetEdgeRef(obj, "FsmGlobalTransitions")
				}));
				List<LogEdge> list = GetStateEdges(obj, ctx).ToList();
				ReferenceLogNode referenceLogNode = new ReferenceLogNode();
				if (list.Count != 0)
				{
					referenceLogNode.Children = list;
				}
				else
				{
					referenceLogNode.ConciseLog = "[empty]";
				}
				node.Children.Add(new LogEdge
				{
					Node = referenceLogNode,
					Header = "States",
					InCoreHierarchy = true
				});
				node.ExtraHeader = LoggableComponent.GetComponentHeader((Component)(object)obj) + " - " + obj.FsmName;
			}
		}

		[IteratorStateMachine(typeof(<GetStateEdges>d__1))]
		public static IEnumerable<LogEdge> GetStateEdges(PlayMakerFSM fsm, LogContext ctx)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetStateEdges>d__1(-2)
			{
				<>3__fsm = fsm,
				<>3__ctx = ctx
			};
		}
	}
	public class LoggableFsmState : Loggable<ReferenceLogNode, FsmState>
	{
		[CompilerGenerated]
		private sealed class <GetActionEdges>d__1 : IEnumerable<LogEdge>, IEnumerable, IEnumerator<LogEdge>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private LogEdge <>2__current;

			private int <>l__initialThreadId;

			private FsmState state;

			public FsmState <>3__state;

			private LogContext ctx;

			public LogContext <>3__ctx;

			private int <idx>5__2;

			private FsmStateAction[] <>7__wrap2;

			private int <>7__wrap3;

			LogEdge IEnumerator<LogEdge>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetActionEdges>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0094;
				}
				<>1__state = -1;
				<idx>5__2 = 0;
				<>7__wrap2 = state.Actions;
				<>7__wrap3 = 0;
				goto IL_00b2;
				IL_0094:
				<idx>5__2++;
				<>7__wrap3++;
				goto IL_00b2;
				IL_00b2:
				if (<>7__wrap3 < <>7__wrap2.Length)
				{
					FsmStateAction obj = <>7__wrap2[<>7__wrap3];
					if (!ctx.DumpOptions.OmitIfNotFull || ctx.IsCoreObject(obj))
					{
						<>2__current = new LogEdge(obj, <idx>5__2.ToString())
						{
							InCoreHierarchy = true
						};
						<>1__state = 1;
						return true;
					}
					goto IL_0094;
				}
				<>7__wrap2 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<LogEdge> IEnumerable<LogEdge>.GetEnumerator()
			{
				<GetActionEdges>d__1 <GetActionEdges>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetActionEdges>d__ = this;
				}
				else
				{
					<GetActionEdges>d__ = new <GetActionEdges>d__1(0);
				}
				<GetActionEdges>d__.state = <>3__state;
				<GetActionEdges>d__.ctx = <>3__ctx;
				return <GetActionEdges>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<LogEdge>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, FsmState obj, LogContext ctx)
		{
			node.ConciseLog = obj.Name + " (" + obj.GetPrettyNameFromObject() + ")";
			if (ctx.IsCoreObject(obj))
			{
				node.Children.Add(LogEdge.GetEdgeRef(obj, "Transitions"));
				List<LogEdge> list = GetActionEdges(obj, ctx).ToList();
				ReferenceLogNode referenceLogNode = new ReferenceLogNode();
				if (list.Count != 0)
				{
					referenceLogNode.Children = list;
				}
				else
				{
					referenceLogNode.ConciseLog = "[empty]";
				}
				node.Children.Add(new LogEdge
				{
					Node = referenceLogNode,
					Header = "Actions",
					InCoreHierarchy = true
				});
				node.ExtraHeader = "--- " + typeof(FsmState).Name + " - " + obj.Name;
			}
		}

		[IteratorStateMachine(typeof(<GetActionEdges>d__1))]
		public static IEnumerable<LogEdge> GetActionEdges(FsmState state, LogContext ctx)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetActionEdges>d__1(-2)
			{
				<>3__state = state,
				<>3__ctx = ctx
			};
		}
	}
	public class LoggableFsmTransition : Loggable<ValueLogNode, FsmTransition>
	{
		public override void Fill(ValueLogNode node, FsmTransition obj, LogContext ctx)
		{
			node.ConciseLog = obj.EventName + " => " + obj.ToState;
		}
	}
	public class LoggableFsmEvent : Loggable<ReferenceLogNode, FsmEvent>
	{
		public override void Fill(ReferenceLogNode node, FsmEvent obj, LogContext ctx)
		{
			string prettyNameFromObject = obj.GetPrettyNameFromObject();
			node.ConciseLog = obj.Name + " [" + prettyNameFromObject + "]";
			DefaultLoggable.FillFields(node, obj, ctx, new List<string>());
			node.ExtraHeader = prettyNameFromObject;
		}
	}
	public class LoggableFsmStateAction : Loggable<ReferenceLogNode, FsmStateAction>
	{
		public override void Fill(ReferenceLogNode node, FsmStateAction obj, LogContext ctx)
		{
			string prettyNameFromObject = obj.GetPrettyNameFromObject();
			node.ConciseLog = prettyNameFromObject + " [" + typeof(FsmStateAction).Name + "]";
			if (ctx.IsCoreObject(obj))
			{
				DefaultLoggable.FillFields(node, obj, ctx, new List<string>());
				node.ExtraHeader = "--- " + typeof(FsmStateAction).Name + " - " + prettyNameFromObject;
			}
		}
	}
	public class LoggableFsmVariables : Loggable<ReferenceLogNode, FsmVariables>
	{
		public override void Fill(ReferenceLogNode node, FsmVariables obj, LogContext ctx)
		{
			new LoggableIEnumerable().Fill(node, obj.GetAllNamedVariablesSorted(), ctx);
		}
	}
	public class LoggableFsmVar : Loggable<ReferenceLogNode, FsmVar>
	{
		public override void Fill(ReferenceLogNode node, FsmVar obj, LogContext ctx)
		{
			object value = obj.GetValue();
			node.ConciseLog = value?.GetType()?.Name ?? "[null]";
			node.Children.Add(new LogEdge(value, "Value"));
		}
	}
	public class LoggableNamedVariable : Loggable<ReferenceLogNode, NamedVariable>
	{
		public override void Fill(ReferenceLogNode node, NamedVariable obj, LogContext ctx)
		{
			string prettyNameFromObject = obj.GetPrettyNameFromObject();
			if (obj.RawValue != null)
			{
				LogNode logNode = LoggableRegistry.ToLog(obj.RawValue, ctx);
				if (obj is FsmArray)
				{
					node.Children.Add(LogEdge.GetEdgeRef(obj, "Name"));
					node.Children.Add(new LogEdge
					{
						Node = logNode,
						Header = "Value"
					});
					node.ExtraHeader = "[" + prettyNameFromObject + "]";
				}
				else
				{
					node.ConciseLog = ((!string.IsNullOrEmpty(obj.Name)) ? ("{ Name: " + obj.Name + ", Value: " + logNode.ConciseLog + " } [" + prettyNameFromObject + "]") : (logNode.ConciseLog + " [" + prettyNameFromObject + "]"));
				}
			}
			else
			{
				node.ConciseLog = ((!string.IsNullOrEmpty(obj.Name)) ? ("{ Name: " + obj.Name + " } [" + prettyNameFromObject + "]") : ("[empty " + prettyNameFromObject + "]"));
			}
		}
	}
	public abstract class Loggable<T1, T2> where T1 : LogNode, new()
	{
		public LogNode ToLog(object obj, LogContext ctx)
		{
			try
			{
				T1 val = new T1();
				Fill(val, (T2)obj, ctx);
				return val;
			}
			catch (Exception ex)
			{
				GameObjectDumpPlugin.LogError(ex.Message + ", " + this.GetPrettyNameFromObject() + ", " + obj.GetPrettyNameFromObject());
			}
			return new ValueLogNode
			{
				ConciseLog = "[Loggable failed to get LogNode]"
			};
		}

		public abstract void Fill(T1 node, T2 obj, LogContext ctx);
	}
	public static class LoggableRegistry
	{
		[CompilerGenerated]
		private sealed class <ComputeAllMembers>d__24 : IEnumerable<MemberInfo>, IEnumerable, IEnumerator<MemberInfo>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MemberInfo <>2__current;

			private int <>l__initialThreadId;

			private Type t;

			public Type <>3__t;

			private BindingFlags <flags>5__2;

			private Type <current>5__3;

			private FieldInfo[] <>7__wrap3;

			private int <>7__wrap4;

			private PropertyInfo[] <>7__wrap5;

			MemberInfo IEnumerator<MemberInfo>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ComputeAllMembers>d__24(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<current>5__3 = null;
				<>7__wrap3 = null;
				<>7__wrap5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<flags>5__2 = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
					<current>5__3 = t;
					goto IL_0120;
				case 1:
					<>1__state = -1;
					<>7__wrap4++;
					goto IL_008e;
				case 2:
					{
						<>1__state = -1;
						<>7__wrap4++;
						goto IL_00f8;
					}
					IL_0120:
					if (!(<current>5__3 != null) || !(<current>5__3 != typeof(object)))
					{
						break;
					}
					<>7__wrap3 = <current>5__3.GetFields(<flags>5__2);
					<>7__wrap4 = 0;
					goto IL_008e;
					IL_00f8:
					if (<>7__wrap4 < <>7__wrap5.Length)
					{
						PropertyInfo propertyInfo = <>7__wrap5[<>7__wrap4];
						<>2__current = propertyInfo;
						<>1__state = 2;
						return true;
					}
					<>7__wrap5 = null;
					<current>5__3 = <current>5__3.BaseType;
					goto IL_0120;
					IL_008e:
					if (<>7__wrap4 < <>7__wrap3.Length)
					{
						FieldInfo fieldInfo = <>7__wrap3[<>7__wrap4];
						<>2__current = fieldInfo;
						<>1__state = 1;
						return true;
					}
					<>7__wrap3 = null;
					<>7__wrap5 = <current>5__3.GetProperties(<flags>5__2);
					<>7__wrap4 = 0;
					goto IL_00f8;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MemberInfo> IEnumerable<MemberInfo>.GetEnumerator()
			{
				<ComputeAllMembers>d__24 <ComputeAllMembers>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ComputeAllMembers>d__ = this;
				}
				else
				{
					<ComputeAllMembers>d__ = new <ComputeAllMembers>d__24(0);
				}
				<ComputeAllMembers>d__.t = <>3__t;
				return <ComputeAllMembers>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MemberInfo>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <ComputeSerializableFields>d__23 : IEnumerable<FieldInfo>, IEnumerable, IEnumerator<FieldInfo>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private FieldInfo <>2__current;

			private int <>l__initialThreadId;

			private Type type;

			public Type <>3__type;

			private BindingFlags <flags>5__2;

			private Type <current>5__3;

			private IEnumerator<FieldInfo> <>7__wrap3;

			FieldInfo IEnumerator<FieldInfo>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ComputeSerializableFields>d__23(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<current>5__3 = null;
				<>7__wrap3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00cc;
					}
					<>1__state = -1;
					<flags>5__2 = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
					<current>5__3 = type;
					goto IL_00f7;
					IL_00cc:
					if (<>7__wrap3.MoveNext())
					{
						FieldInfo current = <>7__wrap3.Current;
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap3 = null;
					<current>5__3 = <current>5__3.BaseType;
					goto IL_00f7;
					IL_00f7:
					if (<current>5__3 != null && <current>5__3 != typeof(object))
					{
						<>7__wrap3 = (from f in <current>5__3.GetFields(<flags>5__2)
							where f.IsPublic || ((MemberInfo)f).GetCustomAttribute<SerializeField>() != null
							where f.GetCustomAttribute<ObsoleteAttribute>() == null
							select f).GetEnumerator();
						<>1__state = -3;
						goto IL_00cc;
					}
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap3 != null)
				{
					<>7__wrap3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<FieldInfo> IEnumerable<FieldInfo>.GetEnumerator()
			{
				<ComputeSerializableFields>d__23 <ComputeSerializableFields>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ComputeSerializableFields>d__ = this;
				}
				else
				{
					<ComputeSerializableFields>d__ = new <ComputeSerializableFields>d__23(0);
				}
				<ComputeSerializableFields>d__.type = <>3__type;
				return <ComputeSerializableFields>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<FieldInfo>)this).GetEnumerator();
			}
		}

		private static readonly Dictionary<Type, object?> _loggableCache = new Dictionary<Type, object>();

		private static readonly HashSet<Type> _registeredForeignTypes = new HashSet<Type>();

		private static readonly Dictionary<Type, object> _registeredLoggables = new Dictionary<Type, object>();

		private static readonly Dictionary<Type, FieldInfo[]> _serializableFieldsCache = new Dictionary<Type, FieldInfo[]>();

		private static readonly Dictionary<Type, PropertyInfo[]> _getPropertiesCache = new Dictionary<Type, PropertyInfo[]>();

		private static readonly Dictionary<Type, MemberInfo[]> _allMembersCache = new Dictionary<Type, MemberInfo[]>();

		private static readonly Dictionary<(Type type, string name), MemberInfo?> _memberLookupCache = new Dictionary<(Type, string), MemberInfo>();

		private static readonly Dictionary<Type, MethodInfo?> _toLogMethodCache = new Dictionary<Type, MethodInfo>();

		public static DefaultLoggable DefaultLoggable { get; } = new DefaultLoggable();


		public static DefaultForeignLoggable DefaultForeignLoggable { get; } = new DefaultForeignLoggable();


		public static void Register(Type type)
		{
			if (!(type == typeof(object)))
			{
				_registeredForeignTypes.Add(type);
				GameObjectDumpPlugin.Log($"[LogRegistry] added foreign type {type} with default logging");
			}
		}

		public static void Register<T1, T2>(Loggable<T1, T2> instance) where T1 : LogNode, new()
		{
			if (!(typeof(T2) == typeof(object)))
			{
				_registeredLoggables[typeof(T2)] = instance;
				GameObjectDumpPlugin.Log("[LogRegistry] added " + instance.GetType().Name + " - " + typeof(T2).FullName);
			}
		}

		public static LogNode ToLog(object obj, LogContext ctx)
		{
			Type type = obj.GetType();
			if (_loggableCache.TryGetValue(type, out object value))
			{
				if (value == null)
				{
					return DefaultLoggable.ToLog(obj, ctx);
				}
				return InvokeToLog(value, obj, ctx);
			}
			if (_registeredForeignTypes.Any((Type ft) => ft.IsAssignableFrom(type)))
			{
				_loggableCache[type] = DefaultForeignLoggable;
				return DefaultForeignLoggable.ToLog(obj, ctx);
			}
			if (_registeredLoggables.TryGetValue(type, out object value2))
			{
				_loggableCache[type] = value2;
				return InvokeToLog(value2, obj, ctx);
			}
			object obj2 = null;
			int num = int.MaxValue;
			foreach (KeyValuePair<Type, object> registeredLoggable in _registeredLoggables)
			{
				if (registeredLoggable.Key.IsAssignableFrom(type))
				{
					int inheritanceDistance = GetInheritanceDistance(type, registeredLoggable.Key);
					if (inheritanceDistance < num)
					{
						obj2 = registeredLoggable.Value;
						num = inheritanceDistance;
					}
				}
			}
			_loggableCache[type] = obj2;
			if (obj2 == null)
			{
				return DefaultLoggable.ToLog(obj, ctx);
			}
			return InvokeToLog(obj2, obj, ctx);
		}

		public static FieldInfo[] GetSerializableFieldsCached(Type type)
		{
			if (_serializableFieldsCache.TryGetValue(type, out FieldInfo[] value))
			{
				return value;
			}
			value = ComputeSerializableFields(type).ToArray();
			_serializableFieldsCache[type] = value;
			return value;
		}

		public static PropertyInfo[] GetGetPropertiesCached(Type type)
		{
			if (_getPropertiesCache.TryGetValue(type, out PropertyInfo[] value))
			{
				return value;
			}
			value = (from p in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
				where p.CanRead && p.GetIndexParameters().Length == 0
				select p into f
				where f.GetCustomAttribute<ObsoleteAttribute>() == null
				select f).ToArray();
			_getPropertiesCache[type] = value;
			return value;
		}

		public static MemberInfo[] GetAllMembersCached(Type type)
		{
			if (_allMembersCache.TryGetValue(type, out MemberInfo[] value))
			{
				return value;
			}
			value = ComputeAllMembers(type).ToArray();
			_allMembersCache[type] = value;
			return value;
		}

		public static MemberInfo? GetMemberCached(Type type, string name)
		{
			(Type, string) key = (type, name);
			if (_memberLookupCache.TryGetValue(key, out MemberInfo value))
			{
				return value;
			}
			Type type2 = type;
			while (type2 != null)
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				FieldInfo field = type2.GetField(name, bindingAttr);
				if (field != null)
				{
					return _memberLookupCache[key] = field;
				}
				PropertyInfo property = type2.GetProperty(name, bindingAttr);
				if (property != null)
				{
					return _memberLookupCache[key] = property;
				}
				type2 = type2.BaseType;
			}
			return _memberLookupCache[key] = null;
		}

		internal static void Initialize()
		{
			GameObjectDumpPlugin.Log("[LogRegistry] initializing...");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (typeof(DefaultLoggable).IsAssignableFrom(type) || type.IsAbstract || type.IsInterface || type.ContainsGenericParameters)
				{
					continue;
				}
				Type type2 = FindLoggableBaseType(type);
				if (!(type2 == null))
				{
					Type type3 = type2.GetGenericArguments()[1];
					try
					{
						ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
						object value = (((object)constructor != null) ? constructor.Invoke(null) : FormatterServices.GetUninitializedObject(type));
						_registeredLoggables[type3] = value;
						GameObjectDumpPlugin.Log("[LogRegistry] added " + type.Name + " - " + type3.FullName);
					}
					catch (Exception ex)
					{
						GameObjectDumpPlugin.LogWarning("[LogRegistry] Failed to create " + type.FullName + ": " + ex.Message);
					}
				}
			}
		}

		internal static void ClearReflectionCaches()
		{
			_serializableFieldsCache.Clear();
			_getPropertiesCache.Clear();
			_allMembersCache.Clear();
			_memberLookupCache.Clear();
			_toLogMethodCache.Clear();
		}

		[IteratorStateMachine(typeof(<ComputeSerializableFields>d__23))]
		private static IEnumerable<FieldInfo> ComputeSerializableFields(Type type)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ComputeSerializableFields>d__23(-2)
			{
				<>3__type = type
			};
		}

		[IteratorStateMachine(typeof(<ComputeAllMembers>d__24))]
		private static IEnumerable<MemberInfo> ComputeAllMembers(Type t)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ComputeAllMembers>d__24(-2)
			{
				<>3__t = t
			};
		}

		private static Type? FindLoggableBaseType(Type t)
		{
			while (t != null && t != typeof(object))
			{
				if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Loggable<, >))
				{
					return t;
				}
				t = t.BaseType;
			}
			return null;
		}

		private static MethodInfo? GetToLogMethodCached(Type t)
		{
			if (_toLogMethodCache.TryGetValue(t, out MethodInfo value))
			{
				return value;
			}
			value = t.GetMethod("ToLog", BindingFlags.Instance | BindingFlags.Public);
			_toLogMethodCache[t] = value;
			return value;
		}

		private static int GetInheritanceDistance(Type derived, Type baseType)
		{
			if (baseType.IsInterface)
			{
				return GetInterfaceDistance(derived, baseType);
			}
			int num = 0;
			Type type = derived;
			while (type != null)
			{
				if (type == baseType)
				{
					return num;
				}
				num++;
				type = type.BaseType;
			}
			return int.MaxValue;
		}

		private static int GetInterfaceDistance(Type type, Type iface)
		{
			if (!iface.IsInterface || !iface.IsAssignableFrom(type))
			{
				return int.MaxValue;
			}
			HashSet<Type> hashSet = new HashSet<Type>();
			Queue<(Type, int)> queue = new Queue<(Type, int)>();
			queue.Enqueue((type, 0));
			while (queue.Count > 0)
			{
				var (type2, num) = queue.Dequeue();
				if (type2 == iface)
				{
					return num;
				}
				if (hashSet.Add(type2))
				{
					if (type2.BaseType != null)
					{
						queue.Enqueue((type2.BaseType, num + 1));
					}
					Type[] interfaces = type2.GetInterfaces();
					foreach (Type item in interfaces)
					{
						queue.Enqueue((item, num + 1));
					}
				}
			}
			return int.MaxValue;
		}

		private static LogNode InvokeToLog(object loggable, object obj, LogContext ctx)
		{
			MethodInfo toLogMethodCached = GetToLogMethodCached(loggable.GetType());
			if ((object)toLogMethodCached == null)
			{
				GameObjectDumpPlugin.LogWarning("[LogRegistry] Missing ToLog() on " + loggable.GetType().FullName);
				return new ValueLogNode
				{
					ConciseLog = "[reflection error]"
				};
			}
			return (LogNode)toLogMethodCached.Invoke(loggable, new object[2] { obj, ctx });
		}
	}
	public class LoggableUnityObject : Loggable<ReferenceLogNode, Object>
	{
		public override void Fill(ReferenceLogNode node, Object obj, LogContext ctx)
		{
			node.ConciseLog = obj.name + " [" + obj.GetPrettyNameFromObject() + "]";
			DefaultLoggable.FillFields(node, obj, ctx, new List<string>(2) { "name", "hideFlags" });
		}
	}
	public class LoggableGameObject : Loggable<ReferenceLogNode, GameObject>
	{
		[CompilerGenerated]
		private sealed class <GetChildGoEdges>d__2 : IEnumerable<LogEdge>, IEnumerable, IEnumerator<LogEdge>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private LogEdge <>2__current;

			private int <>l__initialThreadId;

			private GameObject go;

			public GameObject <>3__go;

			private LogContext ctx;

			public LogContext <>3__ctx;

			private int <idx>5__2;

			private IEnumerator <>7__wrap2;

			LogEdge IEnumerator<LogEdge>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetChildGoEdges>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Expected O, but got Unknown
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00bb;
					}
					<>1__state = -1;
					<idx>5__2 = 0;
					<>7__wrap2 = ((Transform)(((object)go.transform) ?? ((object)new Transform()))).GetEnumerator();
					<>1__state = -3;
					goto IL_00cb;
					IL_00cb:
					if (<>7__wrap2.MoveNext())
					{
						Transform val = (Transform)<>7__wrap2.Current;
						if (!ctx.DumpOptions.OmitIfNotFull || ctx.IsCoreObject(((Component)val).gameObject))
						{
							<>2__current = new LogEdge(((Component)val).gameObject, <idx>5__2.ToString())
							{
								InCoreHierarchy = true
							};
							<>1__state = 1;
							return true;
						}
						goto IL_00bb;
					}
					<>m__Finally1();
					<>7__wrap2 = null;
					return false;
					IL_00bb:
					<idx>5__2++;
					goto IL_00cb;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<LogEdge> IEnumerable<LogEdge>.GetEnumerator()
			{
				<GetChildGoEdges>d__2 <GetChildGoEdges>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetChildGoEdges>d__ = this;
				}
				else
				{
					<GetChildGoEdges>d__ = new <GetChildGoEdges>d__2(0);
				}
				<GetChildGoEdges>d__.go = <>3__go;
				<GetChildGoEdges>d__.ctx = <>3__ctx;
				return <GetChildGoEdges>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<LogEdge>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetComponentEdges>d__1 : IEnumerable<LogEdge>, IEnumerable, IEnumerator<LogEdge>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private LogEdge <>2__current;

			private int <>l__initialThreadId;

			private GameObject go;

			public GameObject <>3__go;

			private LogContext ctx;

			public LogContext <>3__ctx;

			private int <idx>5__2;

			private Component[] <>7__wrap2;

			private int <>7__wrap3;

			LogEdge IEnumerator<LogEdge>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetComponentEdges>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0094;
				}
				<>1__state = -1;
				<idx>5__2 = 0;
				<>7__wrap2 = go.GetComponents<Component>();
				<>7__wrap3 = 0;
				goto IL_00b2;
				IL_0094:
				<idx>5__2++;
				<>7__wrap3++;
				goto IL_00b2;
				IL_00b2:
				if (<>7__wrap3 < <>7__wrap2.Length)
				{
					Component obj = <>7__wrap2[<>7__wrap3];
					if (!ctx.DumpOptions.OmitIfNotFull || ctx.IsCoreObject(obj))
					{
						<>2__current = new LogEdge(obj, <idx>5__2.ToString())
						{
							InCoreHierarchy = true
						};
						<>1__state = 1;
						return true;
					}
					goto IL_0094;
				}
				<>7__wrap2 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<LogEdge> IEnumerable<LogEdge>.GetEnumerator()
			{
				<GetComponentEdges>d__1 <GetComponentEdges>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetComponentEdges>d__ = this;
				}
				else
				{
					<GetComponentEdges>d__ = new <GetComponentEdges>d__1(0);
				}
				<GetComponentEdges>d__.go = <>3__go;
				<GetComponentEdges>d__.ctx = <>3__ctx;
				return <GetComponentEdges>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<LogEdge>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, GameObject obj, LogContext ctx)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			node.ConciseLog = ((Object)obj).name + " [" + obj.GetPrettyNameFromObject() + "]";
			if (ctx.IsCoreObject(obj))
			{
				List<LogEdge> list = GetComponentEdges(obj, ctx).ToList();
				List<LogEdge> list2 = GetChildGoEdges(obj, ctx).ToList();
				List<LogEdge> children = node.Children;
				LogEdge[] obj2 = new LogEdge[7]
				{
					LogEdge.GetEdgeRef(obj, "layer"),
					LogEdge.GetEdgeRef(obj, "activeSelf"),
					LogEdge.GetEdgeRef(obj, "activeInHierarchy"),
					LogEdge.GetEdgeRef(obj, "isStatic"),
					LogEdge.GetEdgeRef(obj, "tag"),
					null,
					null
				};
				Scene scene = obj.scene;
				obj2[5] = new LogEdge(((Scene)(ref scene)).name, "scene");
				obj2[6] = LogEdge.GetEdgeRef(obj, "hideFlags");
				children.AddRange(new <>z__ReadOnlyArray<LogEdge>(obj2));
				ReferenceLogNode referenceLogNode = new ReferenceLogNode();
				if (list.Count != 0)
				{
					referenceLogNode.Children = list;
				}
				else
				{
					referenceLogNode.ConciseLog = "[empty]";
				}
				node.Children.Add(new LogEdge
				{
					Node = referenceLogNode,
					Header = "Components",
					InCoreHierarchy = true
				});
				ReferenceLogNode referenceLogNode2 = new ReferenceLogNode();
				if (list2.Count != 0)
				{
					referenceLogNode2.Children = list2;
				}
				else
				{
					referenceLogNode2.ConciseLog = "[empty]";
				}
				node.Children.Add(new LogEdge
				{
					Node = referenceLogNode2,
					Header = "Children",
					InCoreHierarchy = true
				});
				node.ExtraHeader = "===== GameObject - " + ((Object)obj).name;
			}
		}

		[IteratorStateMachine(typeof(<GetComponentEdges>d__1))]
		public static IEnumerable<LogEdge> GetComponentEdges(GameObject go, LogContext ctx)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetComponentEdges>d__1(-2)
			{
				<>3__go = go,
				<>3__ctx = ctx
			};
		}

		[IteratorStateMachine(typeof(<GetChildGoEdges>d__2))]
		public static IEnumerable<LogEdge> GetChildGoEdges(GameObject go, LogContext ctx)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetChildGoEdges>d__2(-2)
			{
				<>3__go = go,
				<>3__ctx = ctx
			};
		}
	}
	public class LoggableComponent : Loggable<ReferenceLogNode, Component>
	{
		public static string GetComponentHeader(Component c)
		{
			return GetComponentHeader(c.GetPrettyNameFromObject());
		}

		public static string GetComponentHeader(string componentType)
		{
			return "--- " + componentType;
		}

		public static void FillDefaultComponent(ReferenceLogNode node, Component obj)
		{
			string prettyNameFromObject = obj.GetPrettyNameFromObject();
			node.ConciseLog = ((Object)obj).name + " [" + prettyNameFromObject + "]";
			node.ExtraHeader = GetComponentHeader(prettyNameFromObject);
		}

		public override void Fill(ReferenceLogNode node, Component obj, LogContext ctx)
		{
			FillDefaultComponent(node, obj);
			if (ctx.IsCoreObject(obj))
			{
				DefaultLoggable.FillBaseGameType(node, obj, ctx, new List<string>(5) { "name", "hideFlags", "gameObject", "transform", "tag" });
			}
		}
	}
	public class LoggableTransform : Loggable<ReferenceLogNode, Transform>
	{
		public override void Fill(ReferenceLogNode node, Transform obj, LogContext ctx)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			LoggableComponent.FillDefaultComponent(node, (Component)(object)obj);
			if (ctx.IsCoreObject(obj))
			{
				List<LogEdge> children = node.Children;
				LogEdge[] obj2 = new LogEdge[6]
				{
					LogEdge.GetEdgeRef(obj, "position"),
					LogEdge.GetEdgeRef(obj, "localPosition"),
					null,
					null,
					null,
					null
				};
				Quaternion val = obj.rotation;
				obj2[2] = new LogEdge(((Quaternion)(ref val)).eulerAngles, "rotation");
				val = obj.localRotation;
				obj2[3] = new LogEdge(((Quaternion)(ref val)).eulerAngles, "localRotation");
				obj2[4] = LogEdge.GetEdgeRef(obj, "localScale");
				obj2[5] = LogEdge.GetEdgeRef(obj, "childCount");
				children.AddRange(new <>z__ReadOnlyArray<LogEdge>(obj2));
			}
		}
	}
	public class LoggableMonoBehaviour : Loggable<ReferenceLogNode, MonoBehaviour>
	{
		public override void Fill(ReferenceLogNode node, MonoBehaviour obj, LogContext ctx)
		{
			LoggableComponent.FillDefaultComponent(node, (Component)(object)obj);
			if (ctx.IsCoreObject(obj))
			{
				DefaultLoggable.FillBaseGameType(node, obj, ctx, new List<string>(5) { "name", "hideFlags", "gameObject", "transform", "tag" });
			}
		}
	}
	public class Matrix4x4Loggable : Loggable<ReferenceLogNode, Matrix4x4>
	{
		[CompilerGenerated]
		private sealed class <GetLines>d__1 : IEnumerable<LogEdge>, IEnumerable, IEnumerator<LogEdge>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private LogEdge <>2__current;

			private int <>l__initialThreadId;

			private Matrix4x4 obj;

			public Matrix4x4 <>3__obj;

			private int <i>5__2;

			LogEdge IEnumerator<LogEdge>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetLines>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 4)
				{
					<>2__current = new LogEdge
					{
						Node = new ValueLogNode
						{
							ConciseLog = $"{((Matrix4x4)(ref obj))[<i>5__2, 0],12:F6}\t{((Matrix4x4)(ref obj))[<i>5__2, 1],12:F6}\t{((Matrix4x4)(ref obj))[<i>5__2, 2],12:F6}\t{((Matrix4x4)(ref obj))[<i>5__2, 3],12:F6}"
						},
						Header = ""
					};
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<LogEdge> IEnumerable<LogEdge>.GetEnumerator()
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				<GetLines>d__1 <GetLines>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetLines>d__ = this;
				}
				else
				{
					<GetLines>d__ = new <GetLines>d__1(0);
				}
				<GetLines>d__.obj = <>3__obj;
				return <GetLines>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<LogEdge>)this).GetEnumerator();
			}
		}

		public override void Fill(ReferenceLogNode node, Matrix4x4 obj, LogContext ctx)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			node.Children.AddRange(GetLines(obj));
		}

		[IteratorStateMachine(typeof(<GetLines>d__1))]
		private static IEnumerable<LogEdge> GetLines(Matrix4x4 obj)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetLines>d__1(-2)
			{
				<>3__obj = obj
			};
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}