Decompiled source of AssetNavigationGeneralExecutionLibraryPlugin v2.2.0

AngelPlugin.dll

Decompiled 2 weeks 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.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Bounce.Singletons;
using DataModel;
using HarmonyLib;
using ModdingTales;
using Newtonsoft.Json;
using TaleSpire.ContentManagement;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AngelPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AngelPlugin")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("AngelPlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("2.2.0.0")]
namespace LordAshes;

[BepInPlugin("org.lordashes.plugins.angel", "Lord Ashes Asset Navigation & Generation Execution Plugin", "2.2.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class AngelPlugin : BaseUnityPlugin
{
	public static class AssetBundleProvider
	{
		public static RegisteredAsset Register(string asset)
		{
			string text = "Processing Asset " + asset;
			AssetInfo assetInfo = null;
			Texture2D portrait = null;
			try
			{
				LoggingPlugin.LogTrace("Loading Asset Bundle " + asset);
				AssetBundle val = null;
				string text2 = "";
				try
				{
					text = "Reading Asset Bundle";
					LoggingPlugin.LogTrace("Reading Asset Bundle " + asset);
					val = AssetBundle.LoadFromFile(asset);
					text = "Reading Info.Txt From Asset Bundle";
					text2 = val.LoadAsset<TextAsset>("info.txt").text;
					text = "Deserializing Info.Txt";
					LoggingPlugin.LogTrace("Parsing Asset Info (Info.txt) Of Asset Bundle " + asset);
				}
				catch (Exception)
				{
					LoggingPlugin.LogTrace("Unable to read Reading Asset Bundle " + asset);
					return null;
				}
				assetInfo = JsonConvert.DeserializeObject<AssetInfo>(text2);
				if (assetInfo.prefab == null || assetInfo.prefab == "")
				{
					assetInfo.prefab = Path.GetFileNameWithoutExtension(asset);
				}
				if (assetInfo.version == null || assetInfo.version == "")
				{
					assetInfo.version = "1.0.0";
				}
				if (assetInfo.author == null || assetInfo.author == "")
				{
					assetInfo.author = "Anonymous";
				}
				if (assetInfo.pack == null || assetInfo.pack == "")
				{
					assetInfo.pack = Path.GetDirectoryName(asset).Substring(Paths.PluginPath.Length);
					assetInfo.pack = assetInfo.pack.Substring(1, assetInfo.pack.IndexOf("\\CustomData") - 1);
				}
				loadingAssets = "Preparing " + assetInfo.pack + " Asset " + assetInfo.name + " (" + assetInfo.prefab + ")";
				LoggingPlugin.LogTrace("Generalizing Asset Bundle Information For " + asset);
				assetInfo.filename = generalizeFileName(asset);
				text = "Conforming Kind";
				string kind = ("CREATURE|AURA|EFFECT|FILTER|PROP|SLAB".Contains(assetInfo.kind.ToUpper()) ? assetInfo.kind : "Creature");
				assetInfo.kind = kind;
				if (assetInfo.category == null || assetInfo.category == "")
				{
					assetInfo.category = assetInfo.kind;
				}
				LoggingPlugin.LogTrace("Preparing Icon (Portrait.png) For " + assetInfo.name + " (" + assetInfo.prefab + ") At " + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + assetInfo.prefab + ".png");
				text = "Getting Icon Under " + assetInfo.prefab;
				try
				{
					portrait = val.LoadAsset<Texture2D>("portrait.png");
				}
				catch (Exception)
				{
					LoggingPlugin.LogTrace("Unable to read Portrait.PNG file of " + asset);
					portrait = null;
				}
				val.Unload(false);
			}
			catch (Exception ex3)
			{
				LoggingPlugin.LogTrace("Stopped Processing " + asset + " At " + text + " Due To " + ex3.Message);
			}
			return new RegisteredAsset
			{
				info = assetInfo,
				portrait = portrait
			};
		}

		public static bool Load(string link, CreatureBoardAsset asset, Transform targetTransform)
		{
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			string[] array = link.Split(new char[1] { '~' });
			try
			{
				LoggingPlugin.LogTrace("Load Asset Bundle: Loading Asset Bundle '" + ungeneralizeFileName(array[0]) + "'");
				AssetBundle val = AssetBundle.LoadFromFile(ungeneralizeFileName(array[0]));
				LoggingPlugin.LogTrace("Load Asset Bundle: Loading Prefab '" + array[1] + "'");
				GameObject val2 = null;
				try
				{
					val2 = val.LoadAsset<GameObject>(array[1]);
					if ((Object)(object)val2 == (Object)null)
					{
						throw new Exception("Load Asset Bundle: Unable To Find Prefab '" + array[1] + "'");
					}
				}
				catch
				{
					LoggingPlugin.LogTrace("Load Asset Bundle: Prefab '" + array[1] + "' Not Found. Available Options Are...");
					foreach (string item in from e in val.GetAllAssetNames()
						where e.ToUpper().EndsWith(".PREFAB")
						select e)
					{
						LoggingPlugin.LogTrace("Load Asset Bundle: Option: Prefab '" + item + "'");
					}
					val2 = val.LoadAsset<GameObject>((from e in val.GetAllAssetNames()
						where e.ToUpper().EndsWith(".PREFAB")
						select e).ElementAt(0));
				}
				LoggingPlugin.LogTrace("Load Asset Bundle: Creating Prefab Instance");
				GameObject val3 = Object.Instantiate<GameObject>(val2);
				CreatureGuid creatureId = asset.CreatureId;
				((Object)val3).name = ((object)(CreatureGuid)(ref creatureId)).ToString() + "~" + link;
				LoggingPlugin.LogTrace("Load Asset Bundle: Parenting Instance " + ((Object)val3).name + " To " + ((Object)((Component)targetTransform).gameObject).name);
				if (array[2].ToUpper() == "CREATURE")
				{
					LoggingPlugin.LogTrace("Load Asset Bundle: Applying Creature Scale Of " + ((MovableBoardAsset)asset).Scale + "x");
					val3.transform.localScale = new Vector3(((MovableBoardAsset)asset).Scale, ((MovableBoardAsset)asset).Scale, ((MovableBoardAsset)asset).Scale);
				}
				val3.transform.position = targetTransform.position;
				val3.transform.rotation = targetTransform.rotation;
				val3.transform.SetParent(targetTransform);
				val3.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
				LoggingPlugin.LogTrace("Load Asset Bundle: Unload AssetBundle");
				Object.Destroy((Object)(object)val2);
				val.Unload(false);
				PatchSetCreatureFlyingState.Postfix(asset.CreatureId, ((MovableBoardAsset)asset).IsFlying);
				return true;
			}
			catch
			{
				string text = array[0].Substring(Paths.PluginPath.Length + 1);
				text = text.Substring(0, text.IndexOf("\\"));
				LoggingPlugin.LogWarning("Load Asset Bundle: Missing Custom Content Pack (Pack: " + text + ", Prefab: " + array[1] + ")");
				SystemMessage.DisplayInfoText("Missing Content:\r\nPack: " + text + "\r\nPrefab: " + array[1], 10f, 0f);
				return false;
			}
		}
	}

	public class Sequencer
	{
		private string name = "";

		public Sequencer(Elements sequence)
		{
			name = sequence.name;
			Element[] elements = sequence.elements;
			foreach (Element sequence2 in elements)
			{
				LoggingPlugin.LogDebug("Starting Sequencer " + sequence.name);
				((MonoBehaviour)_self).StartCoroutine(processSequence(sequence.target, sequence.name, sequence2));
			}
		}

		private IEnumerator processSequence(CreatureBoardAsset target, string name, Element sequence)
		{
			AnimationStyle animStyle = sequence.style & (AnimationStyle)255;
			bool animLoop = isSet(sequence.style, AnimationStyle.Loop);
			string animClamp = (isSet(sequence.style, AnimationStyle.ClampStart) ? "Start" : (isSet(sequence.style, AnimationStyle.ClampEnd) ? "End" : "None"));
			LoggingPlugin.LogDebug("Animation Style: " + animStyle.ToString() + ", Loop: " + animLoop + ", Clamp: " + animClamp);
			do
			{
				LoggingPlugin.LogDebug("Starting Forward Sequence Of Sequencer " + name + " With Style " + sequence.style);
				if (sequence.audio != null && sequence.audio.Trim() != "")
				{
					HandleAudio(int.Parse(sequence.audio));
				}
				if (sequence.animation != null && sequence.animation.Trim() != "")
				{
					HandleAnimate(int.Parse(sequence.animation));
				}
				do
				{
					if (sequence.style == AnimationStyle.None)
					{
						continue;
					}
					if (sequence.start < sequence.end)
					{
						for (float pace = sequence.start; pace < sequence.end; pace += Math.Abs(sequence.step))
						{
							yield return (object)new WaitForSeconds(0.1f);
							HandleBlendshape(target, sequence.blendShapeIndex, pace);
							if (!sequencers.Contains(target.CreatureId))
							{
								break;
							}
						}
						continue;
					}
					for (float pace2 = sequence.start; pace2 > sequence.end; pace2 += -1f * Math.Abs(sequence.step))
					{
						yield return (object)new WaitForSeconds(0.1f);
						HandleBlendshape(target, sequence.blendShapeIndex, pace2);
						if (!sequencers.Contains(target.CreatureId))
						{
							break;
						}
					}
				}
				while (sequencers.Contains(target.CreatureId) && !isSet(sequence.style, AnimationStyle.PingPong) && isSet(sequence.style, AnimationStyle.Loop));
				if (sequencers.Contains(target.CreatureId) || !isSet(sequence.style, AnimationStyle.PingPong))
				{
					continue;
				}
				LoggingPlugin.LogDebug("Starting Reverse Sequence Of Sequencer " + name + " With Style " + sequence.style);
				if (sequence.end < sequence.start)
				{
					for (float pace4 = sequence.end; pace4 < sequence.start; pace4 += Math.Abs(sequence.step))
					{
						yield return (object)new WaitForSeconds(0.1f);
						HandleBlendshape(target, sequence.blendShapeIndex, pace4);
						if (!sequencers.Contains(target.CreatureId))
						{
							break;
						}
					}
					continue;
				}
				for (float pace3 = sequence.end; pace3 > sequence.start; pace3 += -1f * Math.Abs(sequence.step))
				{
					yield return (object)new WaitForSeconds(0.1f);
					HandleBlendshape(target, sequence.blendShapeIndex, pace3);
					if (!sequencers.Contains(target.CreatureId))
					{
						break;
					}
				}
			}
			while (sequencers.Contains(target.CreatureId) && isSet(sequence.style, AnimationStyle.Loop));
			if (isSet(sequence.style, AnimationStyle.ClampStart))
			{
				LoggingPlugin.LogTrace("Ending Sequencer " + name + " Sequence With Starting Sequence Values");
				HandleBlendshape(target, sequence.blendShapeIndex, sequence.start);
			}
			else if (isSet(sequence.style, AnimationStyle.ClampEnd))
			{
				LoggingPlugin.LogTrace("Ending Sequencer " + name + " Sequence With Ending Sequence Values");
				HandleBlendshape(target, sequence.blendShapeIndex, sequence.end);
			}
			else
			{
				LoggingPlugin.LogTrace("Ending Sequencer " + name + " Sequence With Current Sequence Values");
			}
			LoggingPlugin.LogDebug("Removing Sequencer " + name + " With Style " + sequence.style);
			if (sequencers.Contains(target.CreatureId))
			{
				sequencers.Remove(target.CreatureId);
			}
		}

		private void HandleBlendshape(CreatureBoardAsset target, int blendShapeIndex, float blendShapeValue)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			string[] obj = new string[9]
			{
				"Requesting BlendShape ",
				(blendShapeIndex - 1).ToString(),
				" To ",
				blendShapeValue.ToString(),
				" On ",
				target.Name,
				" (",
				null,
				null
			};
			CreatureGuid creatureId = target.CreatureId;
			obj[7] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj[8] = ")";
			LoggingPlugin.LogDebug(string.Concat(obj));
			SkinnedMeshRenderer componentInChildren = ((Component)target).GetComponentInChildren<SkinnedMeshRenderer>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				LoggingPlugin.LogTrace(componentInChildren.sharedMesh.blendShapeCount + " Blendshapes available");
				LoggingPlugin.LogDebug("Setting BlendShape " + (blendShapeIndex - 1) + " To " + blendShapeValue);
				componentInChildren.SetBlendShapeWeight(blendShapeIndex - 1, blendShapeValue);
			}
		}

		private bool isSet(AnimationStyle value, AnimationStyle mask)
		{
			return (value & mask) == mask;
		}
	}

	public class AssetInfo
	{
		[NonSerialized]
		public Internal _internal = new Internal();

		public string name { get; set; } = "";


		public string prefab { get; set; } = "";


		public string pack { get; set; } = "";


		public string filename { get; set; } = "";


		public string kind { get; set; } = "";


		public string category { get; set; } = "";


		public string groupName { get; set; } = "Custom Content";


		public string description { get; set; } = "";


		public string tags { get; set; } = "";


		public string author { get; set; } = "";


		public string version { get; set; } = "Unversioned";


		public string comment { get; set; } = "";


		public float size { get; set; } = 1f;


		public string[] variants { get; set; } = null;


		public string[] animationOrder { get; set; } = null;


		public Elements[] blendshapes { get; set; } = null;


		public Dictionary<string, string> handler { get; set; } = new Dictionary<string, string>();

	}

	public enum AnimationStyle
	{
		None = 0,
		Single = 1,
		PingPong = 2,
		Loop = 0x80,
		ClampStart = 0x100,
		ClampNone = 0x200,
		ClampEnd = 0x400
	}

	public class Elements
	{
		[NonSerialized]
		public CreatureBoardAsset target;

		public string name { get; set; } = "No Name";


		public Element[] elements { get; set; }
	}

	public class Element
	{
		public string audio { get; set; }

		public string animation { get; set; }

		public AnimationStyle style { get; set; } = AnimationStyle.None;


		public int blendShapeIndex { get; set; }

		public float start { get; set; }

		public float end { get; set; }

		public float step { get; set; }
	}

	public class Internal
	{
		public PlayerGuid spawnPlayer { get; set; }
	}

	[HarmonyPatch(typeof(CreaturePresenter), "OnCreatureAdded")]
	public class PatchOnCreatureAdded
	{
		public static void Postfix(in CreatureDataV3 creatureData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			BuildContent(creatureData);
		}
	}

	[HarmonyPatch(typeof(CreatureBoardAsset), "OnCreatureDataChanged")]
	public class PatchOnCreatureDataChanged
	{
		public static bool Prefix(CreatureBoardAsset __instance, in CreatureDataV3 newData)
		{
			//IL_020b: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			CreatureGuid creatureId;
			if ((Object)(object)__instance != (Object)null && __instance.Link != newData.Link)
			{
				string text = ((__instance.Link == null) ? "" : Convert.ToString(__instance.Link));
				string text2 = ((newData.Link == null) ? "" : Convert.ToString(newData.Link));
				string[] obj = new string[6] { "Creature ", __instance.Name, " (", null, null, null };
				creatureId = __instance.CreatureId;
				obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
				obj[4] = "): Link Changed To ";
				obj[5] = text2;
				LoggingPlugin.LogInfo(string.Concat(obj));
				if (text2 != "")
				{
					if (text.ToUpper().Contains("FILTER") || text2.ToUpper().Contains("FILTER"))
					{
						LoggingPlugin.LogInfo("About To Destroy Filter");
						DestroyFilter(__instance);
					}
					else
					{
						LoggingPlugin.LogInfo("About To Destroy Content");
						DestroyContent(__instance);
					}
					string[] obj2 = new string[5] { "Creature ", __instance.Name, " (", null, null };
					creatureId = __instance.CreatureId;
					obj2[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
					obj2[4] = "): Getting New Content CreatureData";
					LoggingPlugin.LogInfo(string.Concat(obj2));
					CreatureDataV3 creatureData = default(CreatureDataV3);
					CreatureManager.TryGetCreatureData(__instance.CreatureId, ref creatureData);
					string[] obj3 = new string[5] { "Creature ", __instance.Name, " (", null, null };
					creatureId = __instance.CreatureId;
					obj3[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
					obj3[4] = "): Building New Content";
					LoggingPlugin.LogInfo(string.Concat(obj3));
					BuildContent(creatureData);
				}
				else if (text.ToUpper().Contains("FILTER"))
				{
					DestroyFilter(__instance);
				}
			}
			else
			{
				string[] obj4 = new string[5] { "Creature ", __instance.Name, " (", null, null };
				creatureId = __instance.CreatureId;
				obj4[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
				obj4[4] = "): Data Changed";
				LoggingPlugin.LogInfo(string.Concat(obj4));
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(CreatureManager), "DeleteCreature")]
	public class PatchDeleteCreature
	{
		public static bool Prefix(CreatureGuid creatureId, UniqueCreatureGuid uniqueId, bool deleteUniqueFromBackend)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			LoggingPlugin.LogTrace("Destroying Creature " + ((object)(CreatureGuid)(ref creatureId)).ToString());
			CreatureBoardAsset val = null;
			CreaturePresenter.TryGetAsset(creatureId, ref val);
			if ((Object)(object)val != (Object)null && val.Link != null && val.Link.Contains("assetBundleInfo="))
			{
				LoggingPlugin.LogDebug("Creature " + val.Name + " (" + ((object)(CreatureGuid)(ref creatureId)).ToString() + "): Destroying With ANGEL Content");
				CreatureManager.SetLink(creatureId, "");
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(CreatureBoardAsset), "Select")]
	public class PatchSelect
	{
		public static void Postfix(CreatureBoardAsset __instance)
		{
			if (__instance.Link == null || !__instance.Link.Contains("assetBundleInfo="))
			{
				return;
			}
			string[] array = __instance.Link.Substring(__instance.Link.IndexOf("assetBundleInfo=") + "assetBundleInfo=".Length).Split(new char[1] { '&' });
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(new char[1] { '~' });
				if (array3[2].ToUpper() == "CREATURE" || array3[2].ToUpper() == "FILTER")
				{
					((MonoBehaviour)_self).StartCoroutine(setPortraitBadge(array3[1]));
				}
			}
		}
	}

	[HarmonyPatch(typeof(CreatureBoardAsset), "OnVisibilityChanged")]
	public class PatchOnOp
	{
		public static void Postfix(CreatureBoardAsset __instance)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance != (Object)null) || (hideState.ContainsKey(__instance.CreatureId) && hideState[__instance.CreatureId] == ((MovableBoardAsset)__instance).IsVisible))
			{
				return;
			}
			if (!hideState.ContainsKey(__instance.CreatureId))
			{
				hideState.Add(__instance.CreatureId, ((MovableBoardAsset)__instance).IsVisible);
			}
			else
			{
				hideState[__instance.CreatureId] = ((MovableBoardAsset)__instance).IsVisible;
			}
			string[] obj = new string[6] { "Creature ", __instance.Name, " (", null, null, null };
			CreatureGuid creatureId = __instance.CreatureId;
			obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj[4] = "): Changing Render State To ";
			obj[5] = ((MovableBoardAsset)__instance).IsVisible.ToString();
			LoggingPlugin.LogTrace(string.Concat(obj));
			foreach (GameObject item in Object.FindObjectsOfType<GameObject>(false).Where(delegate(GameObject go)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				string name = ((Object)go).name;
				CreatureGuid creatureId2 = __instance.CreatureId;
				return name.Contains(((object)(CreatureGuid)(ref creatureId2)).ToString());
			}))
			{
				Renderer[] componentsInChildren = item.GetComponentsInChildren<Renderer>();
				foreach (Renderer val in componentsInChildren)
				{
					val.enabled = ((MovableBoardAsset)__instance).IsVisible;
				}
			}
		}
	}

	[HarmonyPatch(typeof(CreatureManager), "SetCreatureFlyingState")]
	public class PatchSetCreatureFlyingState
	{
		public static void Postfix(CreatureGuid creatureId, bool flyingState)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreatureBoardAsset val = null;
			CreaturePresenter.TryGetAsset(creatureId, ref val);
			if ((Object)(object)val != (Object)null)
			{
				((MonoBehaviour)_self).StartCoroutine(AdjustBaseForFlying(((Component)val).gameObject, flyingState));
			}
		}
	}

	public class RegisteredAsset
	{
		public AssetInfo info = null;

		public Texture2D portrait = null;
	}

	public delegate RegisteredAsset RegisterCallback(string asset);

	public delegate bool LoadCallback(string link, CreatureBoardAsset asset, Transform targetTransform);

	public class Provider
	{
		public string name = "Fluffy";

		public string fileType = ".ABC";

		public RegisterCallback register = null;

		public LoadCallback load = null;
	}

	public static class Utility
	{
		public static void PostOnMainPage(BaseUnityPlugin plugin)
		{
			string text = "Lord Ashes" + ("Lord Ashes".ToUpper().EndsWith("S") ? "'" : "'s");
			ModdingUtils.AddPluginToMenuList(plugin, text);
		}

		public static bool isBoardLoaded()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			return SimpleSingletonBehaviour<CameraController>.HasInstance && SingletonStateMBehaviour<BoardSessionManager, State<BoardSessionManager>>.HasInstance && !BoardSessionManager.IsLoading && BoardSessionManager.CurrentBoardInfo.Id != default(BoardGuid);
		}

		public static GameObject FindInHierarchy(GameObject start, string seekName)
		{
			List<GameObject> results = new List<GameObject>();
			bool done = false;
			Traverse(start.transform, seekName, null, single: true, ref results, ref done);
			return (results.Count > 0) ? results.ElementAt(0) : null;
		}

		public static GameObject FindInHierarchyViaPartialName(GameObject start, string seekName)
		{
			List<GameObject> results = new List<GameObject>();
			bool done = false;
			Traverse(start.transform, seekName, null, single: true, ref results, ref done, partial: true);
			return (results.Count > 0) ? results.ElementAt(0) : null;
		}

		public static GameObject[] FindAllInHierarchy(GameObject start, string seekName)
		{
			List<GameObject> results = new List<GameObject>();
			bool done = false;
			Traverse(start.transform, seekName, null, single: false, ref results, ref done);
			return results.ToArray();
		}

		public static GameObject[] FindAllInHierarchyViaPartialName(GameObject start, string seekName)
		{
			List<GameObject> results = new List<GameObject>();
			bool done = false;
			Traverse(start.transform, seekName, null, single: false, ref results, ref done, partial: true);
			return results.ToArray();
		}

		public static GameObject FindWithComponentInHierarchy(GameObject start, string seekType)
		{
			List<GameObject> results = new List<GameObject>();
			bool done = false;
			Traverse(start.transform, null, seekType, single: true, ref results, ref done);
			return (results.Count > 0) ? results.ElementAt(0) : null;
		}

		public static GameObject[] FindAllWithComponentInHierarchy<T>(GameObject start, string seekType)
		{
			List<GameObject> results = new List<GameObject>();
			bool done = false;
			Traverse(start.transform, null, seekType, single: false, ref results, ref done);
			return results.ToArray();
		}

		public static void Traverse(Transform root, string seekName, string seekType, bool single, ref List<GameObject> results, ref bool done, bool partial = false)
		{
			try
			{
				if ((seekName == null || seekName == ((Object)((Component)root).gameObject).name || (partial && ((Object)((Component)root).gameObject).name.Contains(seekName))) && (seekType == null || (Object)(object)((Component)root).GetComponent(seekType) != (Object)null))
				{
					LoggingPlugin.LogTrace("Matched '" + ((Object)((Component)root).gameObject).name + "'");
					results.Add(((Component)root).gameObject);
					if (single)
					{
						done = true;
						return;
					}
				}
				foreach (Transform item in ExtensionMethods.Children(root))
				{
					if (!done)
					{
						Traverse(item, seekName, seekType, single, ref results, ref done, partial);
					}
				}
			}
			catch
			{
			}
		}
	}

	private static List<CreatureGuid> sequencers = new List<CreatureGuid>();

	private static Dictionary<CreatureGuid, bool> hideState = new Dictionary<CreatureGuid, bool>();

	public static List<Provider> providers = new List<Provider>();

	public const string Name = "Lord Ashes Asset Navigation & Generation Execution Plugin";

	public const string Guid = "org.lordashes.plugins.angel";

	public const string Version = "2.2.0.0";

	public const string Author = "Lord Ashes";

	public const string PackFolder = "LordAshes-AssetNavigationGeneralExecutionLibraryPlugin";

	private static AngelPlugin _self = null;

	private static string loadingAssets = "";

	private SortedDictionary<string, Dictionary<string, List<AssetInfo>>> menu = new SortedDictionary<string, Dictionary<string, List<AssetInfo>>>(StringComparer.OrdinalIgnoreCase);

	private Dictionary<string, Texture2D> icons = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

	private bool angelMenuOpen = false;

	private bool angelIgnoreClick = false;

	private Texture2D angleMenuBackground = Image.LoadTexture("angel.background.png", (CacheType)999);

	private Texture2D angleMenuUnused = Image.LoadTexture("angel.unused.png", (CacheType)999);

	private Texture2D angleThunderstoreLogo = Image.LoadTexture("Thunderstore_Logo.png", (CacheType)999);

	public Texture2D angelDefaultPortrait = Texture2D.blackTexture;

	private string defaultBaseBlueprint = "";

	private string angelMainMenuSelection = "";

	private string angelGroupMenuSelection = "";

	private int angelGroupMenuIndex = 0;

	private int angelAssetMenuIndex = 0;

	private GUIStyle angelGroupMenuEntryStyle = new GUIStyle();

	private GUIStyle angelAssetInfoStyle = new GUIStyle();

	private static string cacheLocation = "";

	private static AssetInfo spawningAsset = null;

	private static bool librarySelectionInProgress = false;

	private static bool analysisInProgress = false;

	private static float filterDelay = 10f;

	private KeyboardShortcut triggerLibrary;

	private KeyboardShortcut triggerAnalysis;

	private KeyboardShortcut triggerCycleMorph;

	private KeyboardShortcut triggerEditLink;

	private KeyboardShortcut modifersSpawnAuras;

	private KeyboardShortcut modifersSpawnMorphs;

	private KeyboardShortcut[] audioTriggers = (KeyboardShortcut[])(object)new KeyboardShortcut[10]
	{
		new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)51, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)52, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)53, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)54, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)55, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)56, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)57, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }),
		new KeyboardShortcut((KeyCode)48, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 })
	};

	private KeyboardShortcut[] animateTriggers = (KeyboardShortcut[])(object)new KeyboardShortcut[10]
	{
		new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)51, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)52, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)53, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)54, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)55, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)56, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)57, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }),
		new KeyboardShortcut((KeyCode)48, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 })
	};

	private KeyboardShortcut[] blendshapeTriggers = (KeyboardShortcut[])(object)new KeyboardShortcut[10]
	{
		new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)51, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)52, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)53, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)54, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)55, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)56, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)57, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }),
		new KeyboardShortcut((KeyCode)48, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 })
	};

	private Dictionary<string, KeyboardShortcut> spawnModifiers = new Dictionary<string, KeyboardShortcut>();

	private void OnGUI()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0343: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0728: Unknown result type (might be due to invalid IL or missing references)
		//IL_0764: Unknown result type (might be due to invalid IL or missing references)
		//IL_0577: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
		int num = 10;
		int num2 = Screen.height - 60 - 32;
		if (angelMenuOpen)
		{
			bool flag = false;
			Vector3 mousePosition = default(Vector3);
			((Vector3)(ref mousePosition))..ctor(0f, 0f, 0f);
			mousePosition = Input.mousePosition;
			mousePosition.y = (float)Screen.height - mousePosition.y;
			if (Input.GetMouseButtonUp(0) && !angelIgnoreClick)
			{
				flag = true;
				((MonoBehaviour)this).StartCoroutine(DebounceCircuit(1f));
			}
			GUI.DrawTexture(new Rect(0f, (float)(Screen.height - 60 - 180), (float)Screen.width, 240f), (Texture)(object)angleMenuBackground);
			foreach (string key in menu.Keys)
			{
				if (key != angelMainMenuSelection)
				{
					GUI.DrawTexture(new Rect((float)num, (float)num2, 32f, 32f), (Texture)(object)icons[key]);
				}
				else
				{
					GUI.DrawTexture(new Rect((float)num, (float)num2, 32f, 32f), (Texture)(object)icons[key + ".selected"]);
				}
				if (flag && IsInside(num, num2, 32, 32, mousePosition))
				{
					clickMainMenu(key);
				}
				num2 -= 36;
			}
			if (angelMainMenuSelection == "")
			{
				return;
			}
			num2 = 861;
			List<string> list = menu[angelMainMenuSelection].Keys.ToList();
			list.Sort();
			if (GUI.Button(new Rect(430f, 861f, 30f, 32f), "▲"))
			{
				angelGroupMenuIndex--;
				if (angelGroupMenuIndex < 0)
				{
					angelGroupMenuIndex = 0;
				}
			}
			if (GUI.Button(new Rect(510f, 861f, 30f, 32f), "▲"))
			{
				angelAssetMenuIndex -= 19;
				if (angelAssetMenuIndex < 0)
				{
					angelAssetMenuIndex = 0;
				}
			}
			for (int i = angelGroupMenuIndex; i < angelGroupMenuIndex + 5; i++)
			{
				if (list.Count > i)
				{
					if (list[i] == angelGroupMenuSelection)
					{
						if (GUI.Button(new Rect(50f, (float)num2, 380f, 32f), list[i]))
						{
							angelGroupMenuSelection = list[i];
						}
					}
					else if (GUI.Button(new Rect(60f, (float)num2, 360f, 32f), list[i]))
					{
						angelGroupMenuSelection = list[i];
					}
				}
				else
				{
					GUI.DrawTexture(new Rect(60f, (float)num2, 360f, 32f), (Texture)(object)angleMenuUnused);
				}
				num2 += 36;
			}
			if (GUI.Button(new Rect(430f, 1004f, 30f, 32f), "▼"))
			{
				angelGroupMenuIndex++;
				if (angelGroupMenuIndex >= list.Count)
				{
					angelGroupMenuIndex = list.Count - 1;
				}
			}
			if (GUI.Button(new Rect(510f, 1004f, 30f, 32f), "▼"))
			{
				angelAssetMenuIndex += 19;
				if (angelAssetMenuIndex >= menu[angelMainMenuSelection][angelGroupMenuSelection].Count)
				{
					angelAssetMenuIndex = menu[angelMainMenuSelection][angelGroupMenuSelection].Count - 1;
				}
			}
			if (angelGroupMenuSelection == "")
			{
				return;
			}
			num2 = 861;
			num = 550;
			for (int j = angelAssetMenuIndex; j < angelAssetMenuIndex + 38; j++)
			{
				if (menu.ContainsKey(angelMainMenuSelection))
				{
					if (menu[angelMainMenuSelection].ContainsKey(angelGroupMenuSelection))
					{
						if (j < menu[angelMainMenuSelection][angelGroupMenuSelection].Count && menu[angelMainMenuSelection][angelGroupMenuSelection].Count > j)
						{
							AssetInfo assetInfo = menu[angelMainMenuSelection][angelGroupMenuSelection][j];
							GUI.DrawTexture(new Rect((float)num, (float)num2, 64f, 64f), (Texture)(object)icons[assetInfo.kind + "." + assetInfo.groupName + "." + assetInfo.prefab], (ScaleMode)0);
							if (IsInside(num, num2, 64, 64, mousePosition))
							{
								GUI.Label(new Rect(600f, (float)(Screen.height - 72), 1000f, 32f), assetInfo.name + ", Type: " + assetInfo.kind + ", Group: " + assetInfo.groupName + ", Pack: " + assetInfo.pack + ", Version: " + assetInfo.version + ", Author: " + assetInfo.author, angelAssetInfoStyle);
								if (flag)
								{
									clickSelection(assetInfo);
								}
							}
						}
					}
					else
					{
						LoggingPlugin.LogInfo("Missing Group " + angelGroupMenuSelection + " In Menu " + angelMainMenuSelection);
					}
				}
				else
				{
					LoggingPlugin.LogInfo("Missing Menu " + angelMainMenuSelection);
				}
				num += 70;
				if (num > 1850)
				{
					num = 550;
					num2 += 70;
				}
			}
			GUI.DrawTexture(new Rect(445f, (float)(Screen.height - 160), 84f, 49f), (Texture)(object)angleThunderstoreLogo);
			if (librarySelectionInProgress)
			{
				GUI.DrawTexture(new Rect(0f, (float)(Screen.height - 60 - 180), (float)Screen.width, 240f), (Texture)(object)angleMenuBackground);
			}
		}
		if (loadingAssets != "")
		{
			GUI.Label(new Rect(10f, (float)(Screen.height - 36), 1900f, 32f), "Loading Pack " + loadingAssets);
		}
	}

	private bool IsInside(int x, int y, int w, int h, Vector3 test)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		if (test.x == 0f && test.y == 0f)
		{
			return false;
		}
		if (test.x < (float)x)
		{
			return false;
		}
		if (test.y < (float)y)
		{
			return false;
		}
		if (test.x > (float)(x + w))
		{
			return false;
		}
		if (test.y > (float)(y + h))
		{
			return false;
		}
		return true;
	}

	private void clickMainMenu(string selection)
	{
		LoggingPlugin.LogDebug("Main Menu Selection " + selection);
		angelMainMenuSelection = selection;
		angelGroupMenuSelection = menu[angelMainMenuSelection].ElementAt(0).Key;
		angelGroupMenuIndex = 0;
		angelAssetMenuIndex = 0;
	}

	private void clickSelection(AssetInfo selection)
	{
		LoggingPlugin.LogDebug("Asset Selection " + selection.name + " (" + selection.prefab + ")");
		HandeLibrarySelection(selection);
	}

	private IEnumerator DebounceCircuit(float surpression)
	{
		angelIgnoreClick = true;
		yield return (object)new WaitForSeconds(surpression);
		angelIgnoreClick = false;
	}

	public void HandeLibrarySelection(AssetInfo selection)
	{
		LoggingPlugin.LogDebug("Asset Library: Selection '" + selection.name + "' Type '" + selection.kind + "'");
		string text = selection.kind;
		if (((KeyboardShortcut)(ref modifersSpawnAuras)).IsPressed())
		{
			text = "AURA";
		}
		if (((KeyboardShortcut)(ref modifersSpawnMorphs)).IsPressed())
		{
			text = "MORPH";
		}
		LoggingPlugin.LogInfo("Asset Library: Spawning '" + selection.name + "' As Type '" + text + "'");
		switch (text.ToUpper())
		{
		case "AURA":
		case "EFFECT":
			HandleAuraEffect(selection);
			break;
		case "AUDIO":
			LoggingPlugin.LogWarning("Audio Not Implemented. Treating As 'Creature'");
			HandleCreature(selection, text.ToUpper());
			break;
		case "SLAB":
			LoggingPlugin.LogWarning("Slab Not Implemented.");
			SystemMessage.DisplayInfoText("Slab Functionality\r\nNot Implemented.\r\nReserved For Future.", 2.5f, 0f);
			HandleCreature(selection, text.ToUpper());
			break;
		case "ENCOUNTER":
			LoggingPlugin.LogWarning("Encounter Not Implemented.");
			SystemMessage.DisplayInfoText("Encounter Functionality\r\nNot Implemented.\r\nReserved For Future.", 2.5f, 0f);
			HandleCreature(selection, text.ToUpper());
			break;
		default:
			HandleCreature(selection, text.ToUpper());
			break;
		}
	}

	private void RemoteRequestHandler(DatumChange change)
	{
		LoggingPlugin.LogInfo("Received Remote Request For " + change.key + " To " + change.value);
		string[] array = change.value.ToString().Split(new char[1] { '=' });
		switch (change.key)
		{
		case "org.lordashes.plugins.angel.audio":
			HandleAudio(int.Parse(array[1]), array[0]);
			break;
		case "org.lordashes.plugins.angel.animate":
			HandleAnimate(int.Parse(array[1]), array[0]);
			break;
		case "org.lordashes.plugins.angel.sequence":
			HandleBlendshape(int.Parse(array[1]), array[0]);
			break;
		}
	}

	public void HandleCreature(AssetInfo selection, string kind)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.LogDebug("AssetBundle Creature '" + selection.name + "' Selected");
		spawningAsset = selection;
		spawningAsset._internal.spawnPlayer = LocalPlayer.Id;
		Exception ex = null;
		librarySelectionInProgress = true;
		if (kind != "MORPH")
		{
			LoggingPlugin.LogDebug("Spawning Creature");
			CreatureManager.TryProcessCreatureBlueprintString(defaultBaseBlueprint, ref ex);
		}
		else
		{
			LoggingPlugin.LogDebug("Spawning Morph");
			CreatureBoardAsset asset = null;
			CreaturePresenter.TryGetAsset(LocalClient.SelectedCreatureId, ref asset);
			if ((Object)(object)asset != (Object)null)
			{
				LoggingPlugin.LogDebug("Checking '" + asset.Link + "' For '" + selection.filename + "~" + selection.prefab + "'");
				if (!asset.Link.Contains(selection.filename + "~" + selection.prefab))
				{
					LoggingPlugin.LogTrace("Adding Morph " + selection.prefab);
					librarySelectionInProgress = true;
					string addition2 = selection.filename + "~" + selection.prefab + "~Morph";
					((MonoBehaviour)_self).StartCoroutine(WaitForCreatureAvailable(LocalClient.SelectedCreatureId, addition2, delegate(CreatureGuid cid, string addition)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						AppendToLink(cid, addition);
						SystemMessage.DisplayInfoText("Creature " + asset.Name + "\r\nMorph " + selection.prefab + "\r\nAdded", 2.5f, 0f);
					}));
				}
				else
				{
					string[] obj = new string[7] { "Removing Morph ", null, null, null, null, null, null };
					CreatureGuid selectedCreatureId = LocalClient.SelectedCreatureId;
					obj[1] = ((object)(CreatureGuid)(ref selectedCreatureId)).ToString();
					obj[2] = "~";
					obj[3] = selection.filename;
					obj[4] = "~";
					obj[5] = selection.prefab;
					obj[6] = "~Morph";
					LoggingPlugin.LogTrace(string.Concat(obj));
					spawningAsset = null;
					((MonoBehaviour)this).StartCoroutine(RemoveLinkReference(asset, selection.filename + "~" + selection.prefab + "~Morph"));
					string[] array = new string[6];
					selectedCreatureId = LocalClient.SelectedCreatureId;
					array[0] = ((object)(CreatureGuid)(ref selectedCreatureId)).ToString();
					array[1] = "~";
					array[2] = selection.filename;
					array[3] = "~";
					array[4] = selection.prefab;
					array[5] = "~Morph";
					Object.Destroy((Object)(object)GameObject.Find(string.Concat(array)));
					SystemMessage.DisplayInfoText("Creature " + asset.Name + "\r\nMorph " + selection.prefab + "\r\nRemoved", 2.5f, 0f);
				}
			}
		}
		if (ex != null)
		{
			LoggingPlugin.LogInfo(ex.Message);
		}
	}

	public void HandleAuraEffect(AssetInfo selection)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.LogDebug("AssetBundle Aura/Effect '" + JsonConvert.SerializeObject((object)selection) + "' Selected");
		spawningAsset = null;
		CreatureBoardAsset val = null;
		CreaturePresenter.TryGetAsset(LocalClient.SelectedCreatureId, ref val);
		string[] obj = new string[8] { "Aura/Effect: ", null, null, null, null, null, null, null };
		CreatureGuid selectedCreatureId = LocalClient.SelectedCreatureId;
		obj[1] = ((object)(CreatureGuid)(ref selectedCreatureId)).ToString();
		obj[2] = "~";
		obj[3] = selection.filename;
		obj[4] = "~";
		obj[5] = selection.prefab;
		obj[6] = "~";
		obj[7] = selection.kind;
		LoggingPlugin.LogDebug(string.Concat(obj));
		if ((Object)(object)val != (Object)null)
		{
			string[] array = new string[7];
			selectedCreatureId = LocalClient.SelectedCreatureId;
			array[0] = ((object)(CreatureGuid)(ref selectedCreatureId)).ToString();
			array[1] = "~";
			array[2] = selection.filename;
			array[3] = "~";
			array[4] = selection.prefab;
			array[5] = "~";
			array[6] = selection.kind;
			if ((Object)(object)GameObject.Find(string.Concat(array)) == (Object)null)
			{
				LoggingPlugin.LogTrace("Aura/Effect: Adding Aura/Effect " + selection.prefab);
				librarySelectionInProgress = true;
				string addition2 = selection.filename + "~" + selection.prefab + "~" + selection.kind;
				((MonoBehaviour)_self).StartCoroutine(WaitForCreatureAvailable(LocalClient.SelectedCreatureId, addition2, delegate(CreatureGuid cid, string addition)
				{
					//IL_0001: 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)
					AppendToLink(cid, addition);
					LoadAssetBundle(cid, addition);
				}));
				return;
			}
			string[] obj2 = new string[8] { "Aura/Effect: Removing Aura/Effect ", null, null, null, null, null, null, null };
			selectedCreatureId = LocalClient.SelectedCreatureId;
			obj2[1] = ((object)(CreatureGuid)(ref selectedCreatureId)).ToString();
			obj2[2] = "~";
			obj2[3] = selection.filename;
			obj2[4] = "~";
			obj2[5] = selection.prefab;
			obj2[6] = "~";
			obj2[7] = selection.kind;
			LoggingPlugin.LogTrace(string.Concat(obj2));
			spawningAsset = null;
			((MonoBehaviour)this).StartCoroutine(RemoveLinkReference(val, selection.filename + "~" + selection.prefab + "~" + selection.kind));
			string[] array2 = new string[7];
			selectedCreatureId = LocalClient.SelectedCreatureId;
			array2[0] = ((object)(CreatureGuid)(ref selectedCreatureId)).ToString();
			array2[1] = "~";
			array2[2] = selection.filename;
			array2[3] = "~";
			array2[4] = selection.prefab;
			array2[5] = "~";
			array2[6] = selection.kind;
			Object.Destroy((Object)(object)GameObject.Find(string.Concat(array2)));
		}
		else
		{
			SystemMessage.DisplayInfoText("Warning:\r\nNo Mini Selected.\r\nSpawning As Creature.", 2.5f, 0f);
			HandleCreature(selection, selection.kind);
		}
	}

	public void HandleAnalysis()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Expected O, but got Unknown
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0536: Unknown result type (might be due to invalid IL or missing references)
		//IL_0587: Unknown result type (might be due to invalid IL or missing references)
		//IL_065e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0735: Unknown result type (might be due to invalid IL or missing references)
		if (analysisInProgress)
		{
			return;
		}
		analysisInProgress = true;
		CreatureBoardAsset val = null;
		CreaturePresenter.TryGetAsset(LocalClient.SelectedCreatureId, ref val);
		List<Tuple<Transform, int>> list = new List<Tuple<Transform, int>>();
		list.Add(new Tuple<Transform, int>(((Component)val).gameObject.transform, 0));
		if ((Object)(object)val != (Object)null)
		{
			string[] obj = new string[5] { val.Name, ", Cid: ", null, null, null };
			CreatureGuid creatureId = val.CreatureId;
			obj[2] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj[3] = ", Type: ";
			InternedContentAddress activeMorphAddress = val.ActiveMorphAddress;
			obj[4] = ((object)(InternedContentAddress)(ref activeMorphAddress)).ToString();
			LoggingPlugin.LogInfo(string.Concat(obj));
			LoggingPlugin.LogInfo(val.Name + ", Hide: " + (val.IsExplicitlyHidden ? "Hidden" : "Not Hidden"));
			LoggingPlugin.LogInfo(val.Name + ", Flying: " + (((MovableBoardAsset)val).IsFlying ? "Flying" : "Not Flying"));
			LoggingPlugin.LogInfo(val.Name + ", Visible: " + (((MovableBoardAsset)val).IsVisible ? "Visible" : "Not Visible"));
			string name = val.Name;
			ShaderStateRef shaderStateRef = val.ShaderStateRef;
			ShaderState state = ((ShaderStateRef)(ref shaderStateRef)).State;
			LoggingPlugin.LogInfo(name + ", In Hide Volume: " + (((ShaderState)(ref state)).IsCreatureHiddenByVolume ? "In Hide Volume" : "Not In Hide Volume"));
			string name2 = val.Name;
			shaderStateRef = val.ShaderStateRef;
			state = ((ShaderStateRef)(ref shaderStateRef)).State;
			LoggingPlugin.LogInfo(name2 + ", LOS: " + (((ShaderState)(ref state)).InActiveLineOfSight ? "In LOS" : "Out Of LOS"));
			GameObject val2 = Utility.FindWithComponentInHierarchy(((Component)val).gameObject, "Animation");
			LoggingPlugin.LogInfo(val.Name + ", Animations? " + ((Object)(object)val2 != (Object)null));
			if ((Object)(object)val2 != (Object)null)
			{
				Animation component = val2.GetComponent<Animation>();
				if ((Object)(object)component != (Object)null)
				{
					int num = 0;
					foreach (AnimationState item in component)
					{
						AnimationState val3 = item;
						string[] obj2 = new string[12]
						{
							"Animation ",
							num.ToString(),
							": ",
							val3.name,
							", Time: ",
							val3.time.ToString(),
							", Length: ",
							val3.length.ToString(),
							", Speed: ",
							val3.speed.ToString(),
							", Mode: ",
							null
						};
						WrapMode wrapMode = val3.wrapMode;
						obj2[11] = ((object)(WrapMode)(ref wrapMode)).ToString();
						LoggingPlugin.LogInfo(string.Concat(obj2));
						num++;
					}
				}
			}
			AudioSource[] componentsInChildren = ((Component)val).gameObject.GetComponentsInChildren<AudioSource>();
			LoggingPlugin.LogInfo(val.Name + ", Audio? " + (componentsInChildren != null && componentsInChildren.Length != 0));
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				int num2 = 0;
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val4 in array)
				{
					LoggingPlugin.LogInfo("Sound " + num2 + ": " + ((Object)val4.clip).name + ", Volume: " + val4.volume + ", Loop: " + val4.loop + ", Time: " + val4.time + ", Length: " + val4.clip.length);
					num2++;
				}
			}
			list.Add(new Tuple<Transform, int>(((Component)val).gameObject.transform, 0));
			while (list.Count > 0)
			{
				Tuple<Transform, int> tuple = list.ElementAt(0);
				list.RemoveAt(0);
				LoggingPlugin.LogInfo("[Level " + tuple.Item2 + ": Name = " + ((Object)((Component)tuple.Item1).gameObject).name + "]");
				Component[] components = ((Component)tuple.Item1).gameObject.GetComponents<Component>();
				foreach (Component val5 in components)
				{
					if (((object)val5).GetType() == typeof(CreatureBoardAsset))
					{
						LoggingPlugin.LogInfo("Level " + tuple.Item2 + " Component: Type = " + ((object)val5).GetType().ToString() + ", Name = " + ((CreatureBoardAsset)val5).Name + ", name = " + ((Object)val5).name);
					}
					else if (((object)val5).GetType() == typeof(MeshRenderer))
					{
						Material[] materials = ((Renderer)(MeshRenderer)val5).materials;
						foreach (Material val6 in materials)
						{
							LoggingPlugin.LogInfo("Level " + tuple.Item2 + " Component: Type = " + ((object)val5).GetType().ToString() + ", Name = " + ((Object)val5).name + ", Material = " + ((Object)val6).name + ", Shader=" + ((Object)val6.shader).name);
						}
					}
					else if (((object)val5).GetType() == typeof(SkinnedMeshRenderer))
					{
						Material[] materials2 = ((Renderer)(SkinnedMeshRenderer)val5).materials;
						foreach (Material val7 in materials2)
						{
							LoggingPlugin.LogInfo("Level " + tuple.Item2 + " Component: Type = " + ((object)val5).GetType().ToString() + ", Name = " + ((Object)val5).name + ", Material = " + ((Object)val7).name + ", Shader=" + ((Object)val7.shader).name);
						}
					}
					else if (((object)val5).GetType() == typeof(ParticleSystemRenderer))
					{
						Material[] materials3 = ((Renderer)(SkinnedMeshRenderer)val5).materials;
						foreach (Material val8 in materials3)
						{
							LoggingPlugin.LogInfo("Level " + tuple.Item2 + " Component: Type = " + ((object)val5).GetType().ToString() + ", Name = " + ((Object)val5).name + ", Material = " + ((Object)val8).name + ", Shader=" + ((Object)val8.shader).name);
						}
					}
					else
					{
						LoggingPlugin.LogInfo("Level " + tuple.Item2 + " Component: Type = " + ((object)val5).GetType().ToString() + ", Name = " + ((Object)val5).name);
					}
				}
				foreach (Transform item2 in ExtensionMethods.Children(tuple.Item1))
				{
					list.Add(new Tuple<Transform, int>(item2, tuple.Item2 + 1));
				}
			}
		}
		analysisInProgress = false;
	}

	private static void DistributeAudio(int selection)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		CreatureGuid selectedCreatureId = LocalClient.SelectedCreatureId;
		AssetDataPlugin.SendInfo("org.lordashes.plugins.angel.audio", ((object)(CreatureGuid)(ref selectedCreatureId)).ToString() + "=" + selection);
	}

	private static void HandleAudio(int selection, string target = null)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		CreatureGuid val = (CreatureGuid)((target == null) ? LocalClient.SelectedCreatureId : new CreatureGuid(target));
		CreatureBoardAsset val2 = null;
		CreaturePresenter.TryGetAsset(val, ref val2);
		if (!((Object)(object)val2 != (Object)null))
		{
			return;
		}
		AudioSource[] audios = ((Component)val2).gameObject.GetComponentsInChildren<AudioSource>();
		switch (selection)
		{
		case 10:
		{
			LoggingPlugin.LogInfo("Audio: Stopping All Audio");
			AudioSource[] array = audios;
			foreach (AudioSource val3 in array)
			{
				val3.Stop();
			}
			return;
		}
		case 9:
			LoggingPlugin.LogInfo("Audio: Playing Named Audio");
			SystemMessage.AskForTextInput("Play Audio", "Audio Name:", "Play", (Action<string>)delegate(string an)
			{
				LoggingPlugin.LogDebug("Audio: Seeking Audio '" + an + "'");
				AudioSource[] array3 = audios;
				foreach (AudioSource val5 in array3)
				{
					if (((Object)val5.clip).name.Contains(an))
					{
						LoggingPlugin.LogInfo("Audio: Playing Audio '" + ((Object)val5.clip).name + "'");
						AudioSource[] array4 = audios;
						foreach (AudioSource val6 in array4)
						{
							val6.Stop();
						}
						val5.Play();
						break;
					}
				}
			}, (Action)null, "Cancel", (Action)null, "");
			return;
		}
		LoggingPlugin.LogTrace("Audio: Playing Audio " + selection);
		if (selection <= audios.Length)
		{
			LoggingPlugin.LogInfo("Audio: Playing Audio '" + ((Object)audios[selection - 1].clip).name + "'");
			AudioSource[] array2 = audios;
			foreach (AudioSource val4 in array2)
			{
				val4.Stop();
			}
			audios[selection - 1].Play();
		}
		else
		{
			SystemMessage.DisplayInfoText("Asset " + val2.Name + " Does Not Have Animation " + selection, 2.5f, 0f);
		}
	}

	private static void DistributeAnimate(int selection)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		CreatureGuid selectedCreatureId = LocalClient.SelectedCreatureId;
		AssetDataPlugin.SendInfo("org.lordashes.plugins.angel.animate", ((object)(CreatureGuid)(ref selectedCreatureId)).ToString() + "=" + selection);
	}

	private static void HandleAnimate(int selection, string target = null)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		CreatureGuid val = (CreatureGuid)((target == null) ? LocalClient.SelectedCreatureId : new CreatureGuid(target));
		CreatureBoardAsset val2 = null;
		CreaturePresenter.TryGetAsset(val, ref val2);
		if (!((Object)(object)val2 != (Object)null))
		{
			return;
		}
		Animation animation = Utility.FindWithComponentInHierarchy(((Component)val2).gameObject, "Animation").GetComponent<Animation>();
		List<AnimationState> anims = new List<AnimationState>(((IEnumerable)animation).Cast<AnimationState>());
		switch (selection)
		{
		case 10:
			LoggingPlugin.LogInfo("Animate: Stopping All Animations");
			animation.Stop();
			return;
		case 9:
			LoggingPlugin.LogDebug("Animate: Toggling Named Animation");
			SystemMessage.AskForTextInput("Play Animation", "Animation Name:", "Play", (Action<string>)delegate(string an)
			{
				LoggingPlugin.LogDebug("Animate: Seeking Animation '" + an + "'");
				foreach (AnimationState item in anims)
				{
					if (item.name.Contains(an))
					{
						LoggingPlugin.LogInfo("Animate: Playing Animation '" + item.name + "'");
						animation.Stop();
						animation.Play(item.name);
						break;
					}
				}
			}, (Action)null, "Cancel", (Action)null, "");
			return;
		}
		LoggingPlugin.LogTrace("Animate: Playing Animation By Index (" + selection + ")");
		AssetInfo assetInfo = GetAssetInfo(val2);
		LoggingPlugin.LogTrace("Animate: Asset Info = " + ((assetInfo != null) ? JsonConvert.SerializeObject((object)assetInfo) : "Null"));
		LoggingPlugin.LogTrace("Animate: AnimationOrder = " + ((assetInfo != null && assetInfo.animationOrder != null) ? JsonConvert.SerializeObject((object)assetInfo.animationOrder) : "Default"));
		if (assetInfo != null && assetInfo.animationOrder != null)
		{
			LoggingPlugin.LogTrace("Animate: Selection " + selection + " vs " + assetInfo.animationOrder.Length + " Ordered Animations");
			if (selection - 1 < assetInfo.animationOrder.Length)
			{
				LoggingPlugin.LogInfo("Animate: Playing Animation '" + assetInfo.animationOrder[selection - 1] + "' (Asset Animation Order)");
				animation.Play(assetInfo.animationOrder[selection - 1]);
				return;
			}
		}
		LoggingPlugin.LogTrace("Animate: Selection " + selection + " vs " + anims.Count + " Available Animations");
		if (selection <= anims.Count)
		{
			LoggingPlugin.LogInfo("Animate: Playing Animation '" + anims[selection - 1].name + "' (Unity Animation Order)");
			animation.Stop();
			animation.Play(anims[selection - 1].name);
		}
		else
		{
			LoggingPlugin.LogWarning("Animate: Asset " + val2.Name + " Does Not Have Animation " + selection);
			SystemMessage.DisplayInfoText("Asset " + val2.Name + " Does Not Have Animation " + selection, 2.5f, 0f);
		}
	}

	private static void DistributeBlendshape(int selection)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		CreatureGuid selectedCreatureId = LocalClient.SelectedCreatureId;
		AssetDataPlugin.SendInfo("org.lordashes.plugins.angel.sequence", ((object)(CreatureGuid)(ref selectedCreatureId)).ToString() + "=" + selection);
	}

	private static void HandleBlendshape(int blendShapeSequenceIndex, string target = null)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.LogDebug("HandleBlendsahpe Entry");
		CreatureGuid val = (CreatureGuid)((target == null) ? LocalClient.SelectedCreatureId : new CreatureGuid(target));
		LoggingPlugin.LogDebug("Cid = " + ((object)(CreatureGuid)(ref val)).ToString() + ", Selection = " + blendShapeSequenceIndex);
		if (blendShapeSequenceIndex < 10 && !sequencers.Contains(val))
		{
			LoggingPlugin.LogDebug("Getting Reference To Asset With Cid " + ((object)(CreatureGuid)(ref val)).ToString());
			CreatureBoardAsset val2 = null;
			CreaturePresenter.TryGetAsset(val, ref val2);
			LoggingPlugin.LogDebug("Getting AssetInfo For Asset With Cid " + ((object)(CreatureGuid)(ref val)).ToString());
			AssetInfo assetInfo = GetAssetInfo(val2);
			LoggingPlugin.LogDebug("Info is null? " + (assetInfo == null));
			LoggingPlugin.LogDebug("Requesting Sequence " + blendShapeSequenceIndex + " (Of " + assetInfo.blendshapes.Length + " Sequences)");
			if (assetInfo.blendshapes != null && blendShapeSequenceIndex <= assetInfo.blendshapes.Length)
			{
				Elements elements = assetInfo.blendshapes.ElementAt(blendShapeSequenceIndex - 1);
				elements.target = val2;
				sequencers.Add(val2.CreatureId);
				new Sequencer(elements);
			}
			else
			{
				LoggingPlugin.LogWarning("Sequence: Asset " + val2.Name + " Does Not Have Sequence " + blendShapeSequenceIndex);
				SystemMessage.DisplayInfoText("Asset " + val2.Name + " Does Not Have Sequence " + blendShapeSequenceIndex, 2.5f, 0f);
			}
		}
		else
		{
			LoggingPlugin.LogDebug("Requesting Sequence Stop (blendShapeIndex=" + blendShapeSequenceIndex + ", AnimatingAssetsCount=" + sequencers.Count + ")");
			if (sequencers.Contains(val))
			{
				sequencers.Remove(val);
			}
		}
	}

	private static IEnumerator WaitForCreatureAvailable(CreatureGuid cid, string addition, Action<CreatureGuid, string> callback)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.LogDebug("Waiting For Creature " + ((object)(CreatureGuid)(ref cid)).ToString() + " To Become Available To Apply " + addition);
		int pass = 0;
		while (pass < 50)
		{
			CreatureBoardAsset asset = null;
			CreaturePresenter.TryGetAsset(cid, ref asset);
			if ((Object)(object)asset != (Object)null)
			{
				string link = ((asset.Link != null) ? asset.Link : "");
				LoggingPlugin.LogDebug("Asset Link: " + link);
				while (pass < 50)
				{
					LoggingPlugin.LogTrace("Pass = " + pass);
					Renderer renderer = ((Component)asset).GetComponentInChildren<Renderer>();
					if ((Object)(object)renderer != (Object)null)
					{
						Material material = renderer.material;
						if ((Object)(object)material != (Object)null)
						{
							LoggingPlugin.LogDebug("Creature " + ((object)(CreatureGuid)(ref cid)).ToString() + " Available");
							callback(cid, addition);
							pass = 2147483646;
							LoggingPlugin.LogTrace("Exiting Wait");
						}
					}
				}
			}
			yield return (object)new WaitForSeconds(0.1f);
		}
		new Exception("Unable to load creature " + ((object)(CreatureGuid)(ref cid)).ToString());
	}

	private static void AppendToLink(CreatureGuid cid, string specs)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		CreatureBoardAsset val = null;
		CreaturePresenter.TryGetAsset(cid, ref val);
		if ((Object)(object)val != (Object)null)
		{
			string text = ((val.Link != null) ? val.Link : "");
			LoggingPlugin.LogDebug("Asset Link: " + text);
			string text2 = text;
			if (text2.Contains("assetBundleInfo="))
			{
				text2 = text2.Substring(0, text2.IndexOf("assetBundleInfo=") - 1);
			}
			LoggingPlugin.LogDebug("Asset Actual Link: " + text2);
			string text3 = text;
			text3 = ((!text3.Contains("assetBundleInfo=")) ? "" : text3.Substring(text3.IndexOf("assetBundleInfo=") + "assetBundleInfo=".Length));
			LoggingPlugin.LogDebug("Asset Previous Extra: " + text3);
			string text4 = specs;
			if (text4.Contains("assetBundleInfo="))
			{
				text4 = text4.Substring(text4.IndexOf("assetBundleInfo=") + "assetBundleInfo=".Length);
			}
			LoggingPlugin.LogDebug("Asset New Extra: " + text4);
			string text5 = text2 + "?assetBundleInfo=" + ((text3 != "") ? (text3 + "&" + text4) : text4);
			if (text5.EndsWith("&"))
			{
				text5 = text5.Substring(0, text5.Length - 1);
			}
			LoggingPlugin.LogDebug("Asset New Link: " + text5);
			CreatureGuid creatureId = val.CreatureId;
			LoggingPlugin.LogDebug("Setting Link On " + ((object)(CreatureGuid)(ref creatureId)).ToString() + " To " + text5);
			CreatureManager.SetLink(val.CreatureId, text5);
		}
	}

	private IEnumerator RemoveLinkReference(CreatureBoardAsset asset, string content)
	{
		string links4 = asset.Link;
		LoggingPlugin.LogTrace("Removing Link Content " + content + " From " + links4);
		links4 = links4.Replace("&" + content, "");
		links4 = links4.Replace(content, "");
		links4 = links4.Replace("=&", "=");
		CreatureManager.SetLink(asset.CreatureId, links4);
		yield return (object)new WaitForSeconds(0.1f);
		LoggingPlugin.LogTrace("Verifying Link " + asset.Link);
	}

	private static void LoadAssetBundle(CreatureGuid cid, string link)
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.LogDebug("Load Asset Bundle: Applying AssetBundle " + link);
		string[] parts = link.Split(new char[1] { '~' });
		if (parts[2].ToUpper() == "MORPH")
		{
			return;
		}
		parts[0] = ungeneralizeFileName(parts[0]);
		Transform val = null;
		CreatureBoardAsset val2 = null;
		CreaturePresenter.TryGetAsset(cid, ref val2);
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		if (parts[2].ToUpper() != "FILTER")
		{
			LoggingPlugin.LogTrace("Load Asset Bundle: Using GameObject Base");
			try
			{
				val = ((Component)((MovableBoardAsset)val2).Rotator).transform;
				val = Utility.FindInHierarchyViaPartialName(((Component)val).gameObject, "CharacterRoot").transform;
			}
			catch (Exception)
			{
				LoggingPlugin.LogError("Load Asset Bundle: Unable to traverse the asset hierarchy at " + ((Object)val).name);
				for (int i = 0; i < ExtensionMethods.Children(val).Count(); i++)
				{
					LoggingPlugin.LogTrace("Load Asset Bundle: Available Children [" + i + "]: " + ((Object)ExtensionMethods.Children(val).ElementAt(i)).name + " (" + ((Object)((Component)ExtensionMethods.Children(val).ElementAt(i)).gameObject).name + ")");
				}
			}
		}
		else
		{
			LoggingPlugin.LogTrace("Load Asset Bundle: Using Camera Base");
			val = ((Component)Camera.main).transform;
			CreatureManager.SetCreatureExplicitHideState(val2.CreatureId, true);
			((MonoBehaviour)_self).StartCoroutine(showContentDespiteHideSettings(val2));
		}
		LoggingPlugin.LogTrace("Load Asset Bundle: Attaching To " + ((Object)val).name);
		LoggingPlugin.LogTrace("Load Asset Bundle: Determining Full AssetBundle Location Based On " + link);
		LoggingPlugin.LogTrace("Load Asset Bundle: Loading Assembly From " + parts[0]);
		Provider provider = providers.Where((Provider p) => p.fileType.ToUpper() == Path.GetExtension(parts[0]).ToUpper() || (p.fileType == "." && Path.GetExtension(parts[0]) == "")).ElementAt(0);
		LoggingPlugin.LogInfo("Involking Handler " + provider.name + " To Load Asset");
		bool flag = provider.load(link, val2, val);
		librarySelectionInProgress = false;
	}

	private static void CycleMorphs(CreatureGuid cid)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: 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_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_0356: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0405: Unknown result type (might be due to invalid IL or missing references)
		CreatureBoardAsset val = null;
		CreaturePresenter.TryGetAsset(cid, ref val);
		if ((Object)(object)val != (Object)null)
		{
			string[] obj = new string[6] { "Morphs: Creature ", val.Name, " (", null, null, null };
			CreatureGuid creatureId = val.CreatureId;
			obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj[4] = ") Has Current Link ";
			obj[5] = val.Link;
			LoggingPlugin.LogTrace(string.Concat(obj));
			string[] array = val.Link.Split(new string[1] { "assetBundleInfo=" }, StringSplitOptions.RemoveEmptyEntries);
			string text = array[0] + "assetBundleInfo=";
			string[] obj2 = new string[6] { "Morphs: Creature ", val.Name, " (", null, null, null };
			creatureId = val.CreatureId;
			obj2[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj2[4] = ") Has CoreLink ";
			obj2[5] = text;
			LoggingPlugin.LogTrace(string.Concat(obj2));
			string[] obj3 = new string[6] { "Morphs: Creature ", val.Name, " (", null, null, null };
			creatureId = val.CreatureId;
			obj3[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj3[4] = ") Has AssetBundle Links ";
			obj3[5] = array[1];
			LoggingPlugin.LogTrace(string.Concat(obj3));
			array = array[1].Split(new char[1] { '&' });
			string[] obj4 = new string[5] { "Morphs: Creature ", val.Name, " (", null, null };
			creatureId = val.CreatureId;
			obj4[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
			obj4[4] = ") Seeking Currently Selected Morph";
			LoggingPlugin.LogTrace(string.Concat(obj4));
			for (int i = 0; i < array.Length; i++)
			{
				string[] obj5 = new string[8] { "Morphs: Creature ", val.Name, " (", null, null, null, null, null };
				creatureId = val.CreatureId;
				obj5[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
				obj5[4] = ") At Index ";
				obj5[5] = i.ToString();
				obj5[6] = " Found Entry ";
				obj5[7] = array[i];
				LoggingPlugin.LogTrace(string.Concat(obj5));
				if (!array[i].EndsWith("~Creature"))
				{
					continue;
				}
				string[] obj6 = new string[7] { "Morphs: Setting Creature ", val.Name, " (", null, null, null, null };
				creatureId = val.CreatureId;
				obj6[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
				obj6[4] = ")'s Index ";
				obj6[5] = i.ToString();
				obj6[6] = " To Inactive (~Morph)";
				LoggingPlugin.LogTrace(string.Concat(obj6));
				array[i] = array[i].Replace("~Creature", "~Morph");
				do
				{
					i++;
					if (i >= array.Length)
					{
						i = 0;
					}
					string[] obj7 = new string[9] { "Morphs: Setting Creature ", val.Name, " (", null, null, null, null, null, null };
					creatureId = val.CreatureId;
					obj7[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
					obj7[4] = ")'s Index ";
					obj7[5] = i.ToString();
					obj7[6] = " Is ";
					obj7[7] = array[i];
					obj7[8] = " While Seeking Next Morph";
					LoggingPlugin.LogTrace(string.Concat(obj7));
				}
				while (!array[i].EndsWith("~Morph"));
				string[] obj8 = new string[7] { "Morphs: Setting Creature ", val.Name, " (", null, null, null, null };
				creatureId = val.CreatureId;
				obj8[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
				obj8[4] = ")'s Index ";
				obj8[5] = i.ToString();
				obj8[6] = " To Active (~Creature)";
				LoggingPlugin.LogTrace(string.Concat(obj8));
				array[i] = array[i].Replace("~Morph", "~Creature");
				string text2 = text + string.Join("&", array);
				string[] obj9 = new string[6] { "Morphs: Setting Creature ", val.Name, " (", null, null, null };
				creatureId = val.CreatureId;
				obj9[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
				obj9[4] = ")'s Link To ";
				obj9[5] = text2;
				LoggingPlugin.LogTrace(string.Concat(obj9));
				CreatureManager.SetLink(val.CreatureId, text2);
				return;
			}
			LoggingPlugin.LogWarning("Morphs: No Creature Found In Link. This Does Not Appear To Be a AssetBundle Asset.");
		}
		else
		{
			LoggingPlugin.LogWarning("Morphs: Creature " + ((object)(CreatureGuid)(ref cid)).ToString() + " Not Found.");
		}
	}

	private static IEnumerator showContentDespiteHideSettings(CreatureBoardAsset asset)
	{
		yield return (object)new WaitForSeconds(filterDelay);
		foreach (GameObject go2 in Object.FindObjectsOfType<GameObject>(false).Where(delegate(GameObject go)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Object)go).name;
			CreatureGuid creatureId = asset.CreatureId;
			return name.Contains(((object)(CreatureGuid)(ref creatureId)).ToString());
		}))
		{
			Renderer[] componentsInChildren = go2.GetComponentsInChildren<Renderer>();
			foreach (Renderer r in componentsInChildren)
			{
				r.enabled = true;
			}
		}
		if (SingletonBehaviour<BoardToolManager>.HasInstance)
		{
			SingletonBehaviour<BoardToolManager>.Instance.SwitchToTool<DefaultBoardTool>((Type)0);
		}
	}

	private static AssetInfo GetAssetInfo(CreatureBoardAsset asset)
	{
		if ((Object)(object)asset != (Object)null)
		{
			string text = (from s in asset.Link.Split(new string[2] { "=", "&" }, StringSplitOptions.RemoveEmptyEntries)
				where s.ToUpper().EndsWith("~CREATURE")
				select s).ElementAt(0);
			text = text.Split(new char[1] { '~' })[1];
			foreach (KeyValuePair<string, Dictionary<string, List<AssetInfo>>> item in _self.menu)
			{
				foreach (KeyValuePair<string, List<AssetInfo>> item2 in item.Value)
				{
					foreach (AssetInfo item3 in item2.Value)
					{
						if (item3.prefab == text)
						{
							return item3;
						}
					}
				}
			}
		}
		return null;
	}

	private static AssetInfo GetAssetInfoFromPrefabName(string prefabName)
	{
		foreach (KeyValuePair<string, Dictionary<string, List<AssetInfo>>> item in _self.menu)
		{
			foreach (KeyValuePair<string, List<AssetInfo>> item2 in item.Value)
			{
				foreach (AssetInfo item3 in item2.Value)
				{
					if (item3.prefab == prefabName)
					{
						return item3;
					}
				}
			}
		}
		return null;
	}

	private static IEnumerator setPortraitBadge(string prefab)
	{
		yield return (object)new WaitForSeconds(0.5f);
		LoggingPlugin.LogTrace("Displaying Creature Portrait " + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + prefab + ".png");
		Image panel = (from i in Object.FindObjectsOfType<Image>()
			where ((Object)i).name == "IMG_CreatureAvatar"
			select i).ElementAt(0);
		panel.sprite = Image.LoadSprite(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + prefab + ".png", (CacheType)999);
	}

	private static IEnumerator AdjustBaseForFlying(GameObject startObject, bool flyingState)
	{
		for (int attempt = 0; attempt < 10; attempt++)
		{
			GameObject content = Utility.FindInHierarchyViaPartialName(startObject, "local[");
			if ((Object)(object)content != (Object)null)
			{
				if (flyingState)
				{
					LoggingPlugin.LogInfo("Creature Part " + ((Object)startObject).name + ": Adjusting Base For To Flying Mode");
					content.transform.localPosition = new Vector3(0f, -0.27f, 0f);
					content.transform.localScale = new Vector3(1f, 0.5f, 1f);
				}
				else
				{
					LoggingPlugin.LogInfo("Creature Part " + ((Object)startObject).name + ": Adjusting Base For To Normal Mode");
					content.transform.localPosition = new Vector3(0f, 0f, 0f);
					content.transform.localScale = new Vector3(1f, 1f, 1f);
				}
				break;
			}
			LoggingPlugin.LogTrace("Waiting For Mini To Switch Flying Modes (Pass=" + (attempt + 1) + ")");
			yield return (object)new WaitForSeconds(1f);
		}
	}

	private static void DestroyContent(CreatureBoardAsset asset)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		string[] obj = new string[5] { "Creature ", asset.Name, " (", null, null };
		CreatureGuid creatureId = asset.CreatureId;
		obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
		obj[4] = "): Destroying ANGEL Content";
		LoggingPlugin.LogInfo(string.Concat(obj));
		GameObject gameObject = ((Component)asset).gameObject;
		creatureId = asset.CreatureId;
		GameObject[] array = Utility.FindAllInHierarchyViaPartialName(gameObject, ((object)(CreatureGuid)(ref creatureId)).ToString());
		GameObject[] array2 = array;
		foreach (GameObject val in array2)
		{
			creatureId = asset.CreatureId;
			LoggingPlugin.LogDebug("Creature " + ((object)(CreatureGuid)(ref creatureId)).ToString() + " Destroying " + ((Object)val).name);
			Object.Destroy((Object)(object)val);
		}
		string[] obj2 = new string[5] { "Creature ", asset.Name, " (", null, null };
		creatureId = asset.CreatureId;
		obj2[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
		obj2[4] = "): Destruction Complete";
		LoggingPlugin.LogInfo(string.Concat(obj2));
	}

	private static void DestroyFilter(CreatureBoardAsset asset)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		string[] obj = new string[5] { "Creature ", asset.Name, " (", null, null };
		CreatureGuid creatureId = asset.CreatureId;
		obj[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
		obj[4] = "): Destroying ANGEL Filter";
		LoggingPlugin.LogInfo(string.Concat(obj));
		for (int i = 0; i < ExtensionMethods.Children(((Component)Camera.main).transform).Count(); i++)
		{
			string name = ((Object)ExtensionMethods.Children(((Component)Camera.main).transform).ElementAt(i)).name;
			creatureId = asset.CreatureId;
			if (name.Contains(((object)(CreatureGuid)(ref creatureId)).ToString()))
			{
				LoggingPlugin.LogDebug("Destroying Filter Content " + ((Object)ExtensionMethods.Children(((Component)Camera.main).transform).ElementAt(i)).name + " On Main Camera");
				Object.Destroy((Object)(object)((Component)ExtensionMethods.Children(((Component)Camera.main).transform).ElementAt(i)).gameObject);
			}
		}
		string[] obj2 = new string[5] { "Creature ", asset.Name, " (", null, null };
		creatureId = asset.CreatureId;
		obj2[3] = ((object)(CreatureGuid)(ref creatureId)).ToString();
		obj2[4] = "): Destruction Complete";
		LoggingPlugin.LogInfo(string.Concat(obj2));
	}

	private static void BuildContent(CreatureDataV3 creatureData)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fc: 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_02c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0457: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.LogDebug("Creature " + creatureData.Alias + " (Id " + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + ") Spawned With Link " + creatureData.Link);
		if (spawningAsset != null)
		{
			string text = spawningAsset.filename + "~" + spawningAsset.prefab + "~" + spawningAsset.kind;
			if (spawningAsset.variants != null)
			{
				string[] variants = spawningAsset.variants;
				foreach (string text2 in variants)
				{
					LoggingPlugin.LogTrace("Creature " + creatureData.Alias + " (" + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + "): Adding ANGEL Variant " + text2);
					text = text + "&" + spawningAsset.filename + "~" + text2 + "~Morph";
				}
			}
			LoggingPlugin.LogInfo("Creature " + creatureData.Alias + " (" + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + "): Creating ANGEL Content " + spawningAsset.prefab + " (" + spawningAsset.kind + ") From " + spawningAsset.filename + " (Link: " + text + ")");
			((MonoBehaviour)_self).StartCoroutine(WaitForCreatureAvailable(creatureData.CreatureId, text, delegate(CreatureGuid cid, string addition)
			{
				//IL_0001: 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)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				AppendToLink(cid, addition);
				LoadAssetBundle(cid, addition);
				CreatureManager.SetCreatureName(cid, spawningAsset.name);
				CreatureManager.SetCreatureScale(cid, 0, spawningAsset.size);
				string[] obj2 = new string[9]
				{
					"Creature ",
					spawningAsset.name,
					" (",
					((object)(CreatureGuid)(ref cid)).ToString(),
					"): Giving Control To ",
					CampaignSessionManager.GetPlayerName(spawningAsset._internal.spawnPlayer),
					" (",
					null,
					null
				};
				PlayerGuid val = spawningAsset._internal.spawnPlayer;
				obj2[7] = ((object)(PlayerGuid)(ref val)).ToString();
				obj2[8] = ")";
				LoggingPlugin.LogDebug(string.Concat(obj2));
				val = default(PlayerGuid);
				CreatureManager.GivePlayerControlOfCreature(val, spawningAsset._internal.spawnPlayer, cid);
			}));
		}
		else if (creatureData.Link != null && creatureData.Link.Contains("assetBundleInfo="))
		{
			CreatureBoardAsset asset = null;
			CreaturePresenter.TryGetAsset(creatureData.CreatureId, ref asset);
			LoggingPlugin.LogDebug("Creature " + (((Object)(object)asset != (Object)null) ? asset.Name : creatureData.Alias) + " (" + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + "): Restoring ANGEL Content");
			string text3 = creatureData.Link.Substring(creatureData.Link.IndexOf("assetBundleInfo=") + "assetBundleInfo=".Length);
			if (text3.Trim() != "")
			{
				string[] array = text3.Split(new char[1] { '&' });
				foreach (string text4 in array)
				{
					LoggingPlugin.LogInfo("Creature " + creatureData.Alias + " (" + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + "): Restoring ANGEL Content " + text4 + " (Link: " + text3 + ")");
					((MonoBehaviour)_self).StartCoroutine(WaitForCreatureAvailable(creatureData.CreatureId, text4, delegate(CreatureGuid cid, string addition)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						LoadAssetBundle(cid, addition);
					}));
				}
			}
			else
			{
				string link = creatureData.Link;
				try
				{
					link = link.Substring(0, link.IndexOf("assetBundleInfo=") - 1);
				}
				catch
				{
					link = "";
				}
				LoggingPlugin.LogTrace("Core Link = " + link);
				((MonoBehaviour)_self).StartCoroutine(WaitForCreatureAvailable(creatureData.CreatureId, link, delegate(CreatureGuid cid, string reset)
				{
					//IL_006a: Unknown result type (might be due to invalid IL or missing references)
					string text5 = (((Object)(object)asset != (Object)null) ? asset.Name : creatureData.Alias);
					LoggingPlugin.LogInfo("Creature " + text5 + " (" + ((object)(CreatureGuid)(ref cid)).ToString() + "): Removing All Aura/Effect Fragment");
					CreatureManager.SetLink(cid, reset);
				}));
			}
		}
		else
		{
			LoggingPlugin.LogInfo("Creature " + creatureData.Alias + " (" + ((object)(CreatureGuid)(ref creatureData.CreatureId)).ToString() + "): Ignoring Regular Creature (Link: " + creatureData.Link + ")");
		}
	}

	public static void Provide(Provider callback)
	{
		providers.Add(callback);
	}

	private IEnumerator RegisterAssets(float initDelay, float itemDelay)
	{
		yield return (object)new WaitForSeconds(initDelay);
		LoggingPlugin.LogDebug("Obtaining List Of Asset Bundles");
		List<string> assets = new List<string>();
		using (List<Provider>.Enumerator enumerator = providers.GetEnumerator())
		{
			while (enumerator.MoveNext())
			{
				GetAssetBundleFiles(extension: enumerator.Current.fileType, root: Paths.PluginPath, assetBundleFiles: ref assets);
			}
		}
		LoggingPlugin.LogDebug("Obtaining Registered Assets");
		menu.Clear();
		string assetListJson = "";
		try
		{
			LoggingPlugin.LogDebug("Reading Registered Asset Packs From " + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\assets");
			assetListJson = File.ReadAllText(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\assets");
			populateMenuDictionary(assetListJson, ref menu);
		}
		catch
		{
		}
		LoggingPlugin.LogTrace("Found " + assets.Count + " Potential Assets");
		bool newAssetsRegistered = false;
		foreach (string asset in assets)
		{
			yield return (object)new WaitForSeconds(itemDelay);
			LoggingPlugin.LogTrace("Analyzing " + asset);
			foreach (Provider provider in providers)
			{
				LoggingPlugin.LogTrace("Provider handles '" + provider.fileType.ToUpper() + "'. Pack is '" + Path.GetExtension(asset).ToUpper() + "'");
			}
			if (providers.Where((Provider p) => p.fileType.ToUpper() == Path.GetExtension(asset).ToUpper() || (p.fileType == "." && Path.GetExtension(asset) == "")).Count() <= 0)
			{
				continue;
			}
			string check = asset.Substring(Paths.PluginPath.Length + 1);
			check = check.Substring(0, check.IndexOf("\\"));
			loadingAssets = "Found " + check;
			check = "\"pack\": \"" + check + "\"";
			LoggingPlugin.LogDebug("Checking Resistered Asset List For " + check);
			if (!assetListJson.Contains(check))
			{
				newAssetsRegistered = true;
				Provider provider2 = providers.Where((Provider p) => p.fileType.ToUpper() == Path.GetExtension(asset).ToUpper() || (p.fileType == "." && Path.GetExtension(asset) == "")).ElementAt(0);
				LoggingPlugin.LogInfo("Involking Handler " + provider2.name + " To Register Asset");
				RegisteredAsset result = null;
				try
				{
					result = provider2.register(asset);
				}
				catch (Exception ex)
				{
					LoggingPlugin.LogError("Registration Error: " + ex);
				}
				if (result != null)
				{
					if ((Object)(object)result.portrait != (Object)null)
					{
						LoggingPlugin.LogInfo("Adding Portrait " + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + result.info.prefab + ".png");
						File.WriteAllBytes(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + result.info.prefab + ".png", ImageConversion.EncodeToPNG(result.portrait));
					}
					else
					{
						LoggingPlugin.LogInfo("Adding Default Portrait " + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + result.info.prefab + ".png");
						File.WriteAllBytes(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + result.info.prefab + ".png", ImageConversion.EncodeToPNG(angelDefaultPortrait));
					}
					if (!menu.ContainsKey(result.info.category))
					{
						LoggingPlugin.LogInfo("Adding Menu " + result.info.category);
						menu.Add(result.info.category, new Dictionary<string, List<AssetInfo>>());
					}
					if (!menu[result.info.category].ContainsKey(result.info.groupName))
					{
						LoggingPlugin.LogInfo("Adding Menu " + result.info.category + " Group " + result.info.groupName);
						menu[result.info.category].Add(result.info.groupName, new List<AssetInfo>());
					}
					LoggingPlugin.LogInfo("Adding Asset " + result.info.name + " (" + result.info.prefab + ") To Menu " + result.info.category + " Group " + result.info.groupName);
					result.info.handler = null;
					menu[result.info.category][result.info.groupName].Add(result.info);
				}
			}
			else
			{
				LoggingPlugin.LogTrace("Skipping Registed Asset " + asset);
			}
		}
		if (newAssetsRegistered)
		{
			LoggingPlugin.LogDebug("Serializing Updated Assets List To " + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\assets");
			try
			{
				File.WriteAllText(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\assets", JsonConvert.SerializeObject((object)getMenuEntries(menu), (Formatting)1));
			}
			catch
			{
			}
		}
		loadingAssets = "";
		LoggingPlugin.LogDebug("Loading Icons");
		icons.Clear();
		foreach (string kind in menu.Keys)
		{
			LoggingPlugin.LogTrace("Loading Icon '" + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.icon." + kind + "'");
			icons.Add(kind, Image.LoadTexture(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.icon." + kind + ".png", (CacheType)999));
			LoggingPlugin.LogTrace("Loading Icon '" + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.icon." + kind + ".selected'");
			icons.Add(kind + ".selected", Image.LoadTexture(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.icon." + kind + ".selected.png", (CacheType)999));
			foreach (string group in menu[kind].Keys)
			{
				foreach (AssetInfo info in menu[kind][group])
				{
					try
					{
						LoggingPlugin.LogTrace("Loading Icon '" + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + info.prefab + "' (Pack: " + info.pack + ")");
						icons.Add(info.category + "." + info.groupName + "." + info.prefab, Image.LoadTexture(Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + info.prefab + ".png", (CacheType)999));
					}
					catch
					{
						LoggingPlugin.LogWarning("Error Loading Icon '" + Paths.PluginPath + "\\" + cacheLocation + "\\.Cache\\angel.portrait." + info.prefab + "' (Pack: " + info.pack + ")");
					}
				}
			}
		}
	}

	private void GetAssetBundleFiles(string root, string extension, ref List<string> assetBundleFiles)
	{
		foreach (string item in Directory.EnumerateFiles(root, "*" + extension))
		{
			LoggingPlugin.LogTrace("Seeking '" + extension.ToUpper() + "'. Found Pack File " + item);
			if (item.ToUpper().Contains("CUSTOMDATA"))
			{
				assetBundleFiles.Add(item);
			}
		}
		foreach (string item2 in Directory.EnumerateDirectories(root))
		{
			GetAssetBundleFiles(item2, extension, ref assetBundleFiles);
		}
	}

	public static string generalizeFileName(string fullpath)
	{
		return fullpath.Replace(Paths.PluginPath, "{PluginInstallPath}");
	}

	public static string ungeneralizeFileName(string fullpath)
	{
		return fullpath.Replace("{PluginInstallPath}", Paths.PluginPath);
	}

	public void populateMenuDictionary(string assetListJson, ref SortedDictionary<string, Dictionary<string, List<AssetInfo>>> menu)
	{
		List<AssetInfo> list = JsonConvert.DeserializeObject<List<AssetInfo>>(assetListJson);
		foreach (AssetInfo item in list)
		{
			if (!menu.ContainsKey(item.category))
			{
				menu.Add(item.category, new Dictionary<string, List<AssetInfo>>());
			}
			if (!menu[item.category].ContainsKey(item.groupName))
			{
				menu[item.category].Add(item.groupName, new List<AssetInfo>());
			}
			menu[item.category][item.groupName].Add(item);
		}
		menu = JsonConvert.DeserializeObject<SortedDictionary<string, Dictionary<string, List<AssetInfo>>>>(assetListJson);
	}

	public List<AssetInfo> getMenuEntries(SortedDictionary<string, Dictionary<string, List<AssetInfo>>> menu)
	{
		List<AssetInfo> list = new List<AssetInfo>();
		foreach (Dictionary<string, List<AssetInfo>> value in menu.Values)
		{
			foreach (List<AssetInfo> value2 in value.Values)
			{
				foreach (AssetInfo item in value2)
				{
					list.Add(item);
				}
			}
		}
		return list;
	}

	private void Awake()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Invalid comparison between Unknown and I4
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: 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_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		_self = this;
		LoggingPlugin.SetLogLevel(((BaseUnityPlugin)this).Config.Bind<DiagnosticLevel>("Settings", "Diagnostic Level", (DiagnosticLevel)3, (ConfigDescription)null).Value);
		string? assemblyQualifiedName = ((object)this).GetType().AssemblyQualifiedName;
		DiagnosticLevel logLevel = LoggingPlugin.GetLogLevel();
		Debug.Log((object)(assemblyQualifiedName + ": Active. (Diagnostic Mode = " + ((object)(DiagnosticLevel)(ref logLevel)).ToString() + ")"));
		if ((int)LoggingPlugin.GetLogLevel() >= 4)
		{
			((MonoBehaviour)this).StartCoroutine(WarnAboutLogLevel());
		}
		defaultBaseBlueprint = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "Blueprint For Default Base For Thunderstore Assets", "AgD_AQAAACMAYnI6MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNzgxYTQwMDABAAAAAH6XEcbunFtBuDQeom6jhAwABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQQAAIEEAACBBAAAgQQAAIEEAACBBAAAgQQAAIEEAACBBAAAgQQAAIEEAACBBAAAgQQAAIEEAACBBAAAgQQAAIEEAACBBAAAA", (ConfigDescription)null).Value;
		float value = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Delay Before Loading Asset Packs", 7f, (ConfigDescription)null).Value;
		filterDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Filter Application Delay", 1f, (ConfigDescription)null).Value;
		cacheLocation = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "Cache Location", "LordAshes-AssetNavigationGeneralExecutionLibraryPlugin", (ConfigDescription)null).Value;
		triggerLibrary = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Toggle Library", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), (ConfigDescription)null).Value;
		triggerCycleMorph = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Trigger Cycle Morphs", new KeyboardShortcut((KeyCode)292, Array.Empty<KeyCode>()), (ConfigDescription)null).Value;
		triggerAnalysis = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Trigger Selected Mini Analysis", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), (ConfigDescription)null).Value;
		triggerEditLink = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Trigger Edit Link", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), (ConfigDescription)null).Value;
		modifersSpawnAuras = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Modifiers For Spawn Auras", new KeyboardShortcut((KeyCode)307, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null).Value;
		modifersSpawnMorphs = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Modifiers For Spawn Morphs", new KeyboardShortcut((KeyCode)303, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null).Value;
		Initialize();
		((MonoBehaviour)this).StartCoroutine(RegisterAssets(value, 0.01f));
	}

	private void Update()
	{
		//IL_0266: Unknown resu