Decompiled source of Acrid Skin Pack v0.1.1

BepInEx/plugins/AcridBogHopper/AcridBogHopper.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE1
{
	[BepInPlugin("eclipseplaytest.acrid.e1", "Acrid - Bog Hopper (Playtest)", "0.2.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class BogHopper : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e1";

		public const string Version = "0.2.4";

		public const string SkinId = "EclipsePlaytestAcridE1BogHopper";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static BogHopper instance;

		private string folder;

		private float deadline;

		private bool registered;

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(BogHopper));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E1_REGISTRATION_BEGIN version=0.2.4 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E1_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.2.4 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				IDisposable disposable = routine as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Frog asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid frog asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Frog asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Frog asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Frog requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration FrogGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "ForeFootL"),
				ContactCues = bank.Find("walk").Cues
			};
			string[] array = new string[6] { "walk", "run", "sprint", "backpedal", "strafe_left", "strafe_right" };
			foreach (string text in array)
			{
				val.TravelPerCycle.Add(text, (text == "backpedal") ? new V3(0f, 1.5f, 0f) : ((text == "strafe_left") ? new V3(1.5f, 0f, 0f) : ((text == "strafe_right") ? new V3(-1.5f, 0f, 0f) : new V3(0f, -1.5f, 0f))));
				val.CyclesPerWorldMetre.Add(text, (text == "sprint") ? 0.24f : ((text == "run") ? 0.22f : 0.18f));
				val.ContactCuesByClip.Add(text, bank.Find(text).Cues);
			}
			val.MaximumCyclesPerSecond = 3.8;
			val.Acceleration = 18.0;
			val.RestartPhase = 0.88;
			val.Presentation = new GaitPresentationSettings();
			val.Validate(bank);
			return val;
		}

		private static ISkinPoseConstraint FrogAim(MotionBank bank, Mesh mesh)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Expected O, but got Unknown
			Func<string, int> func = (string name) => Array.FindIndex(bank.Bones, (Bone b) => b.Name == name);
			int body = func("Body");
			int head = func("Head");
			V3 position = bank.Bones[body].Rest.Position;
			List<V3> list = new List<V3>();
			Vector3[] vertices = mesh.vertices;
			BoneWeight[] boneWeights = mesh.boneWeights;
			for (int num = 0; num < vertices.Length; num++)
			{
				BoneWeight val = boneWeights[num];
				int[] ids = new int[4]
				{
					((BoneWeight)(ref val)).boneIndex0,
					((BoneWeight)(ref val)).boneIndex1,
					((BoneWeight)(ref val)).boneIndex2,
					((BoneWeight)(ref val)).boneIndex3
				};
				float[] values = new float[4]
				{
					((BoneWeight)(ref val)).weight0,
					((BoneWeight)(ref val)).weight1,
					((BoneWeight)(ref val)).weight2,
					((BoneWeight)(ref val)).weight3
				};
				if (Enumerable.Range(0, 4).All((int k) => values[k] < 1E-06f || ids[k] == body || ids[k] == head))
				{
					Vector3 val2 = vertices[num];
					list.Add(new V3(val2.x - position.X, val2.y - position.Y, val2.z - position.Z));
				}
			}
			List<int[]> list2 = new List<int[]>();
			string[] array = new string[2] { "Fore", "Hind" };
			foreach (string text in array)
			{
				string[] array2 = new string[2] { "L", "R" };
				foreach (string text2 in array2)
				{
					list2.Add(new int[3]
					{
						func(text + "Upper" + text2),
						func(text + "Lower" + text2),
						func(text + "Foot" + text2)
					});
				}
			}
			return (ISkinPoseConstraint)new GroundedAimConstraint(bank, "idle", new string[2] { "aim_pitch", "aim_yaw" }, body, list2.ToArray(), list.ToArray(), 0.25f, new string[1] { "death" });
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "frog-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE1BogHopper" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid frog asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE1BogHopper")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = FrogGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE1BogHopper")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = SkinMesh.Read((Stream)memoryStream2, bank);
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "BogHopperAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid frog albedo");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid frog icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE1BogHopper"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE1Frog"
			};
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.16f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinRegistry.Register(new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreatePoseConstraint = (MotionBank motion) => FrogAim(motion, mesh),
				CreateAttachments = (SkinnedMeshRenderer renderer, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(renderer, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer renderer) => (ISkinEffectDriver)new CrocoLeapCosmetics(renderer),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer renderer, MotionBank motion) => (ISkinMotionTiming)new CrocoModelGaitTiming(renderer, motion, gait)
			});
			Mesh val5 = new Mesh
			{
				name = "EclipseAcridE1EmptySpines"
			};
			val5.vertices = Array.Empty<Vector3>();
			val5.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh"),
					mesh = val5,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>();
			((Object)val7).name = "EclipsePlaytestAcridE1BogHopper";
			val7.nameToken = "ECLIPSE_PLAYTEST_ACRID_E1_BOG_HOPPER";
			LanguageAPI.Add(val7.nameToken, "Bog Hopper (Playtest)");
			val7.unlockableDef = null;
			val7.rootObject = modelPrefab;
			val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val7.skinDefParams = val6;
			val7.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val7, mesh);
			val3.skins = (SkinDef[])(controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val7 }).ToArray()).Clone();
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E1_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=frog_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E1_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared frog display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared frog display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E1_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridDuckAndCover/Eclipse.Acrid.E2.DuckAndCover.dll

Decompiled a week 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.Security.Cryptography;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE2
{
	[BepInPlugin("eclipseplaytest.acrid.e2", "Acrid - Duck and Cover (Playtest)", "0.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class DuckAndCover : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public string[] nativeBoneNames;
		}

		public const string Guid = "eclipseplaytest.acrid.e2";

		public const string Version = "0.1.4";

		public const string SkinId = "EclipsePlaytestAcridE2DuckAndCover";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static DuckAndCover instance;

		private string folder;

		private float deadline;

		private bool registered;

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(DuckAndCover));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E2_REGISTRATION_BEGIN version=0.1.4 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E2_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.4 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				IDisposable disposable = routine as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Duck asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid duck asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Duck asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Duck asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Duck requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration DuckGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_016b: 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_0195: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "FootL"),
				ContactCues = bank.Find("walk").Cues,
				TravelPerCycle = { 
				{
					"walk",
					new V3(0f, -3.1666667f, 0f)
				} },
				TravelPerCycle = { 
				{
					"run",
					new V3(0f, -5.3333335f, 0f)
				} },
				TravelPerCycle = { 
				{
					"sprint",
					new V3(0f, -6.3333335f, 0f)
				} },
				TravelPerCycle = { 
				{
					"backpedal",
					new V3(0f, 2.3333333f, 0f)
				} },
				TravelPerCycle = { 
				{
					"strafe_left",
					new V3(-2.3333333f, 0f, 0f)
				} },
				TravelPerCycle = { 
				{
					"strafe_right",
					new V3(2.3333333f, 0f, 0f)
				} },
				MaximumCyclesPerSecond = 1.8,
				Acceleration = 5.0,
				CyclesPerWorldMetre = { { "walk", 0.13571428f } },
				CyclesPerWorldMetre = { 
				{
					"run",
					27f / 140f
				} },
				CyclesPerWorldMetre = { 
				{
					"sprint",
					5f / 34f
				} },
				CyclesPerWorldMetre = { { "backpedal", 0.12857142f } },
				CyclesPerWorldMetre = { { "strafe_left", 0.12857142f } },
				CyclesPerWorldMetre = { { "strafe_right", 0.12857142f } }
			};
			val.Validate(bank);
			return val;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "duck-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE2DuckAndCover" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid duck asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE2DuckAndCover")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = DuckGait(bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = SkinMesh.Read((Stream)memoryStream2, bank);
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "DuckAndCoverAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid duck albedo");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE2DuckAndCover"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE2Duck"
			};
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.16f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinRegistry.Register(new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreateEffects = (SkinnedMeshRenderer renderer) => (ISkinEffectDriver)new CrocoLeapCosmetics(renderer),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer renderer, MotionBank motion) => (ISkinMotionTiming)new CrocoModelGaitTiming(renderer, motion, gait)
			});
			Mesh val5 = new Mesh
			{
				name = "EclipseAcridE2EmptySpines"
			};
			val5.vertices = Array.Empty<Vector3>();
			val5.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh"),
					mesh = val5,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>();
			((Object)val7).name = "EclipsePlaytestAcridE2DuckAndCover";
			val7.nameToken = "ECLIPSE_PLAYTEST_ACRID_E2_DUCK_AND_COVER";
			LanguageAPI.Add(val7.nameToken, "Duck and Cover (Playtest)");
			val7.unlockableDef = null;
			val7.rootObject = modelPrefab;
			val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val7.skinDefParams = val6;
			val7.icon = baseSkin.icon;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val7, mesh);
			val3.skins = (SkinDef[])(controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val7 }).ToArray()).Clone();
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E2_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=uncalibrated"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E2_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared duck display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared duck display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E2_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridE3Animals/AcridE3.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
public sealed class AnimalContactConstraint : ISkinPoseConstraint
{
	private readonly MotionBank bank;

	private readonly int[][] chains;

	private readonly float[] floor;

	public int CorrectedFeet { get; private set; }

	public AnimalContactConstraint(MotionBank bank)
	{
		AnimalContactConstraint animalContactConstraint = this;
		this.bank = bank ?? throw new ArgumentNullException("bank");
		chains = (from prefix in new string[2] { "Fore", "Hind" }
			from side in new string[2] { "L", "R" }
			select new string[3] { "Upper", "Lower", "Foot" }.Select((string part) => Array.FindIndex(bank.Bones, (Bone b) => b.Name == prefix + part + side)).ToArray()).ToArray();
		if (chains.Any((int[] c) => c.Any((int i) => i < 0) || bank.Bones[c[1]].Parent != c[0] || bank.Bones[c[2]].Parent != c[1]))
		{
			throw new ArgumentException("Expected four two-segment limbs");
		}
		Pose[] rest = bank.Bones.Select((Bone b) => b.Rest).ToArray();
		floor = chains.Select((int[] c) => animalContactConstraint.World(rest, c[2]).Position.Z).ToArray();
	}

	private static float Dot(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
	}

	private static float Length(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (float)Math.Sqrt(Dot(v, v));
	}

	private static V3 Unit(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		float num = Length(v);
		if (!(num < 1E-08f))
		{
			return v * (1f / num);
		}
		return new V3(1f, 0f, 0f);
	}

	private static V3 Cross(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		return new V3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
	}

	private static V3 Rotate(Q4 q, V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		Q4 val = q * new Q4(v.X, v.Y, v.Z, 0f) * ((Q4)(ref q)).Inverse;
		return new V3(val.X, val.Y, val.Z);
	}

	private static Q4 FromTo(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		a = Unit(a);
		b = Unit(b);
		float num = Dot(a, b);
		if (num < -0.99999f)
		{
			V3 val = Unit(Cross(a, ((double)Math.Abs(a.X) < 0.8) ? new V3(1f, 0f, 0f) : new V3(0f, 1f, 0f)));
			return new Q4(val.X, val.Y, val.Z, 0f);
		}
		V3 val2 = Cross(a, b);
		Q4 val3 = new Q4(val2.X, val2.Y, val2.Z, 1f + num);
		return ((Q4)(ref val3)).Normalized();
	}

	private Pose World(Pose[] p, int i)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Pose val = p[i];
		int parent = bank.Bones[i].Parent;
		if (parent < 0)
		{
			return val;
		}
		Pose val2 = World(p, parent);
		V3 val3 = val2.Position + Rotate(val2.Rotation, val.Position);
		Q4 val4 = val2.Rotation * val.Rotation;
		return new Pose(val3, ((Q4)(ref val4)).Normalized(), new V3(1f, 1f, 1f));
	}

	private void Solve(Pose[] p, int[] c, Pose target)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: 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_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		Pose val = World(p, c[0]);
		Pose val2 = World(p, c[1]);
		V3 v = target.Position - val.Position;
		float num = Length(p[c[1]].Position);
		float num2 = Length(p[c[2]].Position);
		float num3 = Length(v);
		if (!(num3 > num + num2 + 0.0002f) && !(num3 < Math.Abs(num - num2) - 0.0002f))
		{
			float num4 = Math.Max(Math.Abs(num - num2) + 1E-05f, Math.Min(num + num2 - 1E-05f, num3));
			V3 val3 = Unit(v);
			V3 val4 = val2.Position - val.Position;
			val4 -= val3 * Dot(val4, val3);
			if (Length(val4) < 0.0001f)
			{
				val4 = Cross(val3, ((double)Math.Abs(val3.Z) < 0.8) ? new V3(0f, 0f, 1f) : new V3(0f, 1f, 0f));
			}
			val4 = Unit(val4);
			float num5 = (num * num + num4 * num4 - num2 * num2) / (2f * num4);
			V3 val5 = val.Position + val3 * num5 + val4 * (float)Math.Sqrt(Math.Max(0f, num * num - num5 * num5));
			V3 val6 = val.Position + val3 * num4;
			Q4 val7 = FromTo(Rotate(val.Rotation, p[c[1]].Position), val5 - val.Position) * val.Rotation;
			Q4 val8 = ((Q4)(ref val7)).Normalized();
			val7 = FromTo(Rotate(val2.Rotation, p[c[2]].Position), val6 - val5) * val2.Rotation;
			Q4 val9 = ((Q4)(ref val7)).Normalized();
			int parent = bank.Bones[c[0]].Parent;
			Q4 val10 = ((parent < 0) ? Q4.Identity : World(p, parent).Rotation);
			ref Pose reference = ref p[c[0]];
			val7 = ((Q4)(ref val10)).Inverse * val8;
			reference.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference2 = ref p[c[1]];
			val7 = ((Q4)(ref val8)).Inverse * val9;
			reference2.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference3 = ref p[c[2]];
			val7 = ((Q4)(ref val9)).Inverse * target.Rotation;
			reference3.Rotation = ((Q4)(ref val7)).Normalized();
			CorrectedFeet++;
		}
	}

	public void Apply(MotionLayer[] layers, Pose[] pose, bool grounded)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		CorrectedFeet = 0;
		if (!grounded || layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && s.Clip.Id == "death")))
		{
			return;
		}
		for (int num = 0; num < chains.Length; num++)
		{
			Pose val = World(pose, chains[num][2]);
			if (!(val.Position.Z >= floor[num] - 0.0001f))
			{
				val.Position.Z = floor[num];
				Solve(pose, chains[num], val);
			}
		}
	}
}
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE3
{
	[BepInPlugin("eclipseplaytest.acrid.e3", "Acrid - Trash Panda (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class TrashPanda : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e3";

		public const string Version = "0.1.3";

		public const string SkinId = "EclipsePlaytestAcridE3TrashPanda";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static TrashPanda instance;

		private string folder;

		private float deadline;

		private bool registered;

		private bool registryCommitted;

		private readonly List<Object> pendingObjects = new List<Object>();

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(TrashPanda));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E3_REGISTRATION_BEGIN version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E3_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				(routine as IDisposable)?.Dispose();
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.ReleaseUncommitted();
				}
			}
		}

		private T Own<T>(T value) where T : Object
		{
			pendingObjects.Add((Object)(object)value);
			return value;
		}

		private void ReleaseUncommitted()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (registered || registryCommitted)
			{
				return;
			}
			registration?.Dispose();
			registration = null;
			foreach (AsyncOperationHandle retainedAsset in retainedAssets)
			{
				AsyncOperationHandle current = retainedAsset;
				if (((AsyncOperationHandle)(ref current)).IsValid())
				{
					Addressables.Release(current);
				}
			}
			retainedAssets.Clear();
			foreach (Object pendingObject in pendingObjects)
			{
				if (Object.op_Implicit(pendingObject))
				{
					Object.Destroy(pendingObject);
				}
			}
			pendingObjects.Clear();
		}

		private void ValidateTemplate(GameObject model)
		{
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			if (!Object.op_Implicit((Object)(object)model.GetComponent<Animator>()) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Original Croco template is required");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Animal asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid animal asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Animal asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Animal asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Animal requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration AnimalGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0132: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "HindFootL"),
				ContactCues = bank.Find("walk").Cues
			};
			string[] array = new string[6] { "walk", "run", "sprint", "backpedal", "strafe_left", "strafe_right" };
			foreach (string text in array)
			{
				float num2 = ((text == "run") ? 6.8f : ((text == "sprint") ? 8.4f : 4.4f));
				val.TravelPerCycle.Add(text, (text == "backpedal") ? new V3(0f, num2, 0f) : ((text == "strafe_left") ? new V3(num2, 0f, 0f) : ((text == "strafe_right") ? new V3(0f - num2, 0f, 0f) : new V3(0f, 0f - num2, 0f))));
				val.CyclesPerWorldMetre.Add(text, (text == "sprint") ? 0.2f : ((text == "run") ? 0.23f : 0.26f));
				val.ContactCuesByClip.Add(text, bank.Find(text).Cues);
			}
			val.MaximumCyclesPerSecond = 2.8;
			val.Acceleration = 10.0;
			val.Validate(bank);
			return val;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "animal-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE3TrashPanda" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid animal asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE3TrashPanda")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = AnimalGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE3TrashPanda")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = Own<Mesh>(SkinMesh.Read((Stream)memoryStream2, bank));
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "TrashPandaAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(albedo);
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid animal albedo");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			Own<Texture2D>(icon);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid animal icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE3TrashPanda"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			ValidateTemplate(modelPrefab);
			ValidateTemplate(displayModelPrefab);
			SkinnedMeshRenderer renderer = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh");
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE3TrashPanda"
			};
			Own<Material>(val4);
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.09f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinDefinition val5 = new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreatePoseConstraint = (MotionBank motion) => (ISkinPoseConstraint)(object)new AnimalContactConstraint(motion),
				CreateAttachments = (SkinnedMeshRenderer val9, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(val9, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer val9) => (ISkinEffectDriver)new CrocoLeapCosmetics(val9),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer val9, MotionBank motion) => (ISkinMotionTiming)new CrocoModelGaitTiming(val9, motion, gait)
			};
			Mesh val6 = new Mesh
			{
				name = "EclipseAcridE3EmptySpines"
			};
			Own<Mesh>(val6);
			val6.vertices = Array.Empty<Vector3>();
			val6.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val7 = Own<SkinDefParams>(ScriptableObject.CreateInstance<SkinDefParams>());
			val7.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val7.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderer,
					mesh = val6,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val8 = Own<SkinDef>(ScriptableObject.CreateInstance<SkinDef>());
			((Object)val8).name = "EclipsePlaytestAcridE3TrashPanda";
			val8.nameToken = "ECLIPSE_PLAYTEST_ACRID_E3_TRASH_PANDA";
			LanguageAPI.Add(val8.nameToken, "Trash Panda (Playtest)");
			val8.unlockableDef = null;
			val8.rootObject = modelPrefab;
			val8.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val8.skinDefParams = val7;
			val8.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			Own<Sprite>(val8.icon);
			SkinDef[] array = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			SkinDef[] skins = (SkinDef[])array.Clone();
			AdvancedSkinRegistry.Register(val5);
			registryCommitted = true;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val8, mesh);
			controller.skins = array;
			val3.skins = skins;
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E3_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=species_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E3_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared animal display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared animal display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E3_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			ReleaseUncommitted();
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridE4Animals/AcridE4.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
public sealed class AnimalContactConstraint : ISkinPoseConstraint
{
	private readonly MotionBank bank;

	private readonly int[][] chains;

	private readonly float[] floor;

	public int CorrectedFeet { get; private set; }

	public AnimalContactConstraint(MotionBank bank)
	{
		AnimalContactConstraint animalContactConstraint = this;
		this.bank = bank ?? throw new ArgumentNullException("bank");
		chains = (from prefix in new string[2] { "Fore", "Hind" }
			from side in new string[2] { "L", "R" }
			select new string[3] { "Upper", "Lower", "Foot" }.Select((string part) => Array.FindIndex(bank.Bones, (Bone b) => b.Name == prefix + part + side)).ToArray()).ToArray();
		if (chains.Any((int[] c) => c.Any((int i) => i < 0) || bank.Bones[c[1]].Parent != c[0] || bank.Bones[c[2]].Parent != c[1]))
		{
			throw new ArgumentException("Expected four two-segment limbs");
		}
		Pose[] rest = bank.Bones.Select((Bone b) => b.Rest).ToArray();
		floor = chains.Select((int[] c) => animalContactConstraint.World(rest, c[2]).Position.Z).ToArray();
	}

	private static float Dot(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
	}

	private static float Length(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (float)Math.Sqrt(Dot(v, v));
	}

	private static V3 Unit(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		float num = Length(v);
		if (!(num < 1E-08f))
		{
			return v * (1f / num);
		}
		return new V3(1f, 0f, 0f);
	}

	private static V3 Cross(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		return new V3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
	}

	private static V3 Rotate(Q4 q, V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		Q4 val = q * new Q4(v.X, v.Y, v.Z, 0f) * ((Q4)(ref q)).Inverse;
		return new V3(val.X, val.Y, val.Z);
	}

	private static Q4 FromTo(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		a = Unit(a);
		b = Unit(b);
		float num = Dot(a, b);
		if (num < -0.99999f)
		{
			V3 val = Unit(Cross(a, ((double)Math.Abs(a.X) < 0.8) ? new V3(1f, 0f, 0f) : new V3(0f, 1f, 0f)));
			return new Q4(val.X, val.Y, val.Z, 0f);
		}
		V3 val2 = Cross(a, b);
		Q4 val3 = new Q4(val2.X, val2.Y, val2.Z, 1f + num);
		return ((Q4)(ref val3)).Normalized();
	}

	private Pose World(Pose[] p, int i)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Pose val = p[i];
		int parent = bank.Bones[i].Parent;
		if (parent < 0)
		{
			return val;
		}
		Pose val2 = World(p, parent);
		V3 val3 = val2.Position + Rotate(val2.Rotation, val.Position);
		Q4 val4 = val2.Rotation * val.Rotation;
		return new Pose(val3, ((Q4)(ref val4)).Normalized(), new V3(1f, 1f, 1f));
	}

	private void Solve(Pose[] p, int[] c, Pose target)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: 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_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		Pose val = World(p, c[0]);
		Pose val2 = World(p, c[1]);
		V3 v = target.Position - val.Position;
		float num = Length(p[c[1]].Position);
		float num2 = Length(p[c[2]].Position);
		float num3 = Length(v);
		if (!(num3 > num + num2 + 0.0002f) && !(num3 < Math.Abs(num - num2) - 0.0002f))
		{
			float num4 = Math.Max(Math.Abs(num - num2) + 1E-05f, Math.Min(num + num2 - 1E-05f, num3));
			V3 val3 = Unit(v);
			V3 val4 = val2.Position - val.Position;
			val4 -= val3 * Dot(val4, val3);
			if (Length(val4) < 0.0001f)
			{
				val4 = Cross(val3, ((double)Math.Abs(val3.Z) < 0.8) ? new V3(0f, 0f, 1f) : new V3(0f, 1f, 0f));
			}
			val4 = Unit(val4);
			float num5 = (num * num + num4 * num4 - num2 * num2) / (2f * num4);
			V3 val5 = val.Position + val3 * num5 + val4 * (float)Math.Sqrt(Math.Max(0f, num * num - num5 * num5));
			V3 val6 = val.Position + val3 * num4;
			Q4 val7 = FromTo(Rotate(val.Rotation, p[c[1]].Position), val5 - val.Position) * val.Rotation;
			Q4 val8 = ((Q4)(ref val7)).Normalized();
			val7 = FromTo(Rotate(val2.Rotation, p[c[2]].Position), val6 - val5) * val2.Rotation;
			Q4 val9 = ((Q4)(ref val7)).Normalized();
			int parent = bank.Bones[c[0]].Parent;
			Q4 val10 = ((parent < 0) ? Q4.Identity : World(p, parent).Rotation);
			ref Pose reference = ref p[c[0]];
			val7 = ((Q4)(ref val10)).Inverse * val8;
			reference.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference2 = ref p[c[1]];
			val7 = ((Q4)(ref val8)).Inverse * val9;
			reference2.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference3 = ref p[c[2]];
			val7 = ((Q4)(ref val9)).Inverse * target.Rotation;
			reference3.Rotation = ((Q4)(ref val7)).Normalized();
			CorrectedFeet++;
		}
	}

	public void Apply(MotionLayer[] layers, Pose[] pose, bool grounded)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		CorrectedFeet = 0;
		if (!grounded || layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && s.Clip.Id == "death")))
		{
			return;
		}
		for (int num = 0; num < chains.Length; num++)
		{
			Pose val = World(pose, chains[num][2]);
			if (!(val.Position.Z >= floor[num] - 0.0001f))
			{
				val.Position.Z = floor[num];
				Solve(pose, chains[num], val);
			}
		}
	}
}
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE4
{
	[BepInPlugin("eclipseplaytest.acrid.e4", "Acrid - Good Boy (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class GoodBoy : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e4";

		public const string Version = "0.1.3";

		public const string SkinId = "EclipsePlaytestAcridE4GoodBoy";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static GoodBoy instance;

		private string folder;

		private float deadline;

		private bool registered;

		private bool registryCommitted;

		private readonly List<Object> pendingObjects = new List<Object>();

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(GoodBoy));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E4_REGISTRATION_BEGIN version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E4_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				(routine as IDisposable)?.Dispose();
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.ReleaseUncommitted();
				}
			}
		}

		private T Own<T>(T value) where T : Object
		{
			pendingObjects.Add((Object)(object)value);
			return value;
		}

		private void ReleaseUncommitted()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (registered || registryCommitted)
			{
				return;
			}
			registration?.Dispose();
			registration = null;
			foreach (AsyncOperationHandle retainedAsset in retainedAssets)
			{
				AsyncOperationHandle current = retainedAsset;
				if (((AsyncOperationHandle)(ref current)).IsValid())
				{
					Addressables.Release(current);
				}
			}
			retainedAssets.Clear();
			foreach (Object pendingObject in pendingObjects)
			{
				if (Object.op_Implicit(pendingObject))
				{
					Object.Destroy(pendingObject);
				}
			}
			pendingObjects.Clear();
		}

		private void ValidateTemplate(GameObject model)
		{
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			if (!Object.op_Implicit((Object)(object)model.GetComponent<Animator>()) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Original Croco template is required");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Animal asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid animal asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Animal asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Animal asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Animal requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration AnimalGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0132: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "HindFootL"),
				ContactCues = bank.Find("walk").Cues
			};
			string[] array = new string[6] { "walk", "run", "sprint", "backpedal", "strafe_left", "strafe_right" };
			foreach (string text in array)
			{
				float num2 = ((text == "run") ? 6.8f : ((text == "sprint") ? 8.4f : 4.4f));
				val.TravelPerCycle.Add(text, (text == "backpedal") ? new V3(0f, num2, 0f) : ((text == "strafe_left") ? new V3(num2, 0f, 0f) : ((text == "strafe_right") ? new V3(0f - num2, 0f, 0f) : new V3(0f, 0f - num2, 0f))));
				val.CyclesPerWorldMetre.Add(text, (text == "sprint") ? 0.2f : ((text == "run") ? 0.23f : 0.26f));
				val.ContactCuesByClip.Add(text, bank.Find(text).Cues);
			}
			val.MaximumCyclesPerSecond = 2.8;
			val.Acceleration = 10.0;
			val.Validate(bank);
			return val;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "animal-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE4GoodBoy" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid animal asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE4GoodBoy")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = AnimalGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE4GoodBoy")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = Own<Mesh>(SkinMesh.Read((Stream)memoryStream2, bank));
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "GoodBoyAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(albedo);
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid animal albedo");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			Own<Texture2D>(icon);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid animal icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE4GoodBoy"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			ValidateTemplate(modelPrefab);
			ValidateTemplate(displayModelPrefab);
			SkinnedMeshRenderer renderer = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh");
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE4GoodBoy"
			};
			Own<Material>(val4);
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.09f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinDefinition val5 = new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreatePoseConstraint = (MotionBank motion) => (ISkinPoseConstraint)(object)new AnimalContactConstraint(motion),
				CreateAttachments = (SkinnedMeshRenderer val9, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(val9, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer val9) => (ISkinEffectDriver)new CrocoLeapCosmetics(val9),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer val9, MotionBank motion) => (ISkinMotionTiming)new CrocoModelGaitTiming(val9, motion, gait)
			};
			Mesh val6 = new Mesh
			{
				name = "EclipseAcridE4EmptySpines"
			};
			Own<Mesh>(val6);
			val6.vertices = Array.Empty<Vector3>();
			val6.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val7 = Own<SkinDefParams>(ScriptableObject.CreateInstance<SkinDefParams>());
			val7.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val7.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderer,
					mesh = val6,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val8 = Own<SkinDef>(ScriptableObject.CreateInstance<SkinDef>());
			((Object)val8).name = "EclipsePlaytestAcridE4GoodBoy";
			val8.nameToken = "ECLIPSE_PLAYTEST_ACRID_E4_GOOD_BOY";
			LanguageAPI.Add(val8.nameToken, "Good Boy (Playtest)");
			val8.unlockableDef = null;
			val8.rootObject = modelPrefab;
			val8.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val8.skinDefParams = val7;
			val8.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			Own<Sprite>(val8.icon);
			SkinDef[] array = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			SkinDef[] skins = (SkinDef[])array.Clone();
			AdvancedSkinRegistry.Register(val5);
			registryCommitted = true;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val8, mesh);
			controller.skins = array;
			val3.skins = skins;
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E4_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=species_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E4_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared animal display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared animal display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E4_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			ReleaseUncommitted();
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridE5Animals/AcridE5.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
public sealed class AnimalContactConstraint : ISkinPoseConstraint
{
	private readonly MotionBank bank;

	private readonly int[][] chains;

	private readonly float[] floor;

	public int CorrectedFeet { get; private set; }

	public AnimalContactConstraint(MotionBank bank)
	{
		AnimalContactConstraint animalContactConstraint = this;
		this.bank = bank ?? throw new ArgumentNullException("bank");
		chains = (from prefix in new string[2] { "Fore", "Hind" }
			from side in new string[2] { "L", "R" }
			select new string[3] { "Upper", "Lower", "Foot" }.Select((string part) => Array.FindIndex(bank.Bones, (Bone b) => b.Name == prefix + part + side)).ToArray()).ToArray();
		if (chains.Any((int[] c) => c.Any((int i) => i < 0) || bank.Bones[c[1]].Parent != c[0] || bank.Bones[c[2]].Parent != c[1]))
		{
			throw new ArgumentException("Expected four two-segment limbs");
		}
		Pose[] rest = bank.Bones.Select((Bone b) => b.Rest).ToArray();
		floor = chains.Select((int[] c) => animalContactConstraint.World(rest, c[2]).Position.Z).ToArray();
	}

	private static float Dot(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
	}

	private static float Length(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (float)Math.Sqrt(Dot(v, v));
	}

	private static V3 Unit(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		float num = Length(v);
		if (!(num < 1E-08f))
		{
			return v * (1f / num);
		}
		return new V3(1f, 0f, 0f);
	}

	private static V3 Cross(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		return new V3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
	}

	private static V3 Rotate(Q4 q, V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		Q4 val = q * new Q4(v.X, v.Y, v.Z, 0f) * ((Q4)(ref q)).Inverse;
		return new V3(val.X, val.Y, val.Z);
	}

	private static Q4 FromTo(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		a = Unit(a);
		b = Unit(b);
		float num = Dot(a, b);
		if (num < -0.99999f)
		{
			V3 val = Unit(Cross(a, ((double)Math.Abs(a.X) < 0.8) ? new V3(1f, 0f, 0f) : new V3(0f, 1f, 0f)));
			return new Q4(val.X, val.Y, val.Z, 0f);
		}
		V3 val2 = Cross(a, b);
		Q4 val3 = new Q4(val2.X, val2.Y, val2.Z, 1f + num);
		return ((Q4)(ref val3)).Normalized();
	}

	private Pose World(Pose[] p, int i)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Pose val = p[i];
		int parent = bank.Bones[i].Parent;
		if (parent < 0)
		{
			return val;
		}
		Pose val2 = World(p, parent);
		V3 val3 = val2.Position + Rotate(val2.Rotation, val.Position);
		Q4 val4 = val2.Rotation * val.Rotation;
		return new Pose(val3, ((Q4)(ref val4)).Normalized(), new V3(1f, 1f, 1f));
	}

	private void Solve(Pose[] p, int[] c, Pose target)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: 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_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		Pose val = World(p, c[0]);
		Pose val2 = World(p, c[1]);
		V3 v = target.Position - val.Position;
		float num = Length(p[c[1]].Position);
		float num2 = Length(p[c[2]].Position);
		float num3 = Length(v);
		if (!(num3 > num + num2 + 0.0002f) && !(num3 < Math.Abs(num - num2) - 0.0002f))
		{
			float num4 = Math.Max(Math.Abs(num - num2) + 1E-05f, Math.Min(num + num2 - 1E-05f, num3));
			V3 val3 = Unit(v);
			V3 val4 = val2.Position - val.Position;
			val4 -= val3 * Dot(val4, val3);
			if (Length(val4) < 0.0001f)
			{
				val4 = Cross(val3, ((double)Math.Abs(val3.Z) < 0.8) ? new V3(0f, 0f, 1f) : new V3(0f, 1f, 0f));
			}
			val4 = Unit(val4);
			float num5 = (num * num + num4 * num4 - num2 * num2) / (2f * num4);
			V3 val5 = val.Position + val3 * num5 + val4 * (float)Math.Sqrt(Math.Max(0f, num * num - num5 * num5));
			V3 val6 = val.Position + val3 * num4;
			Q4 val7 = FromTo(Rotate(val.Rotation, p[c[1]].Position), val5 - val.Position) * val.Rotation;
			Q4 val8 = ((Q4)(ref val7)).Normalized();
			val7 = FromTo(Rotate(val2.Rotation, p[c[2]].Position), val6 - val5) * val2.Rotation;
			Q4 val9 = ((Q4)(ref val7)).Normalized();
			int parent = bank.Bones[c[0]].Parent;
			Q4 val10 = ((parent < 0) ? Q4.Identity : World(p, parent).Rotation);
			ref Pose reference = ref p[c[0]];
			val7 = ((Q4)(ref val10)).Inverse * val8;
			reference.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference2 = ref p[c[1]];
			val7 = ((Q4)(ref val8)).Inverse * val9;
			reference2.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference3 = ref p[c[2]];
			val7 = ((Q4)(ref val9)).Inverse * target.Rotation;
			reference3.Rotation = ((Q4)(ref val7)).Normalized();
			CorrectedFeet++;
		}
	}

	public void Apply(MotionLayer[] layers, Pose[] pose, bool grounded)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		CorrectedFeet = 0;
		if (!grounded || layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && s.Clip.Id == "death")))
		{
			return;
		}
		for (int num = 0; num < chains.Length; num++)
		{
			Pose val = World(pose, chains[num][2]);
			if (!(val.Position.Z >= floor[num] - 0.0001f))
			{
				val.Position.Z = floor[num];
				Solve(pose, chains[num], val);
			}
		}
	}
}
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE5
{
	[BepInPlugin("eclipseplaytest.acrid.e5", "Acrid - Ginger Cat (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class GingerCat : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e5";

		public const string Version = "0.1.3";

		public const string SkinId = "EclipsePlaytestAcridE5GingerCat";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static GingerCat instance;

		private string folder;

		private float deadline;

		private bool registered;

		private bool registryCommitted;

		private readonly List<Object> pendingObjects = new List<Object>();

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(GingerCat));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E5_REGISTRATION_BEGIN version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E5_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				(routine as IDisposable)?.Dispose();
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.ReleaseUncommitted();
				}
			}
		}

		private T Own<T>(T value) where T : Object
		{
			pendingObjects.Add((Object)(object)value);
			return value;
		}

		private void ReleaseUncommitted()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (registered || registryCommitted)
			{
				return;
			}
			registration?.Dispose();
			registration = null;
			foreach (AsyncOperationHandle retainedAsset in retainedAssets)
			{
				AsyncOperationHandle current = retainedAsset;
				if (((AsyncOperationHandle)(ref current)).IsValid())
				{
					Addressables.Release(current);
				}
			}
			retainedAssets.Clear();
			foreach (Object pendingObject in pendingObjects)
			{
				if (Object.op_Implicit(pendingObject))
				{
					Object.Destroy(pendingObject);
				}
			}
			pendingObjects.Clear();
		}

		private void ValidateTemplate(GameObject model)
		{
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			if (!Object.op_Implicit((Object)(object)model.GetComponent<Animator>()) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Original Croco template is required");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Animal asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid animal asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Animal asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Animal asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Animal requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration AnimalGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0132: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "HindFootL"),
				ContactCues = bank.Find("walk").Cues
			};
			string[] array = new string[6] { "walk", "run", "sprint", "backpedal", "strafe_left", "strafe_right" };
			foreach (string text in array)
			{
				float num2 = ((text == "run") ? 5.2f : ((text == "sprint") ? 6.6f : 4.4f));
				val.TravelPerCycle.Add(text, (text == "backpedal") ? new V3(0f, num2, 0f) : ((text == "strafe_left") ? new V3(num2, 0f, 0f) : ((text == "strafe_right") ? new V3(0f - num2, 0f, 0f) : new V3(0f, 0f - num2, 0f))));
				val.CyclesPerWorldMetre.Add(text, (text == "sprint") ? 0.2f : ((text == "run") ? 0.23f : 0.26f));
				val.ContactCuesByClip.Add(text, bank.Find(text).Cues);
			}
			val.MaximumCyclesPerSecond = 2.8;
			val.Acceleration = 10.0;
			val.Validate(bank);
			return val;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "animal-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE5GingerCat" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid animal asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE5GingerCat")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = AnimalGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE5GingerCat")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = Own<Mesh>(SkinMesh.Read((Stream)memoryStream2, bank));
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "GingerCatAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(albedo);
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid animal albedo");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			Own<Texture2D>(icon);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid animal icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE5GingerCat"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			ValidateTemplate(modelPrefab);
			ValidateTemplate(displayModelPrefab);
			SkinnedMeshRenderer renderer = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh");
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE5GingerCat"
			};
			Own<Material>(val4);
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.09f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinDefinition val5 = new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreatePoseConstraint = (MotionBank motion) => (ISkinPoseConstraint)(object)new AnimalContactConstraint(motion),
				CreateAttachments = (SkinnedMeshRenderer val9, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(val9, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer val9) => (ISkinEffectDriver)new CrocoLeapCosmetics(val9),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer val9, MotionBank motion) => (ISkinMotionTiming)new CrocoModelGaitTiming(val9, motion, gait)
			};
			Mesh val6 = new Mesh
			{
				name = "EclipseAcridE5EmptySpines"
			};
			Own<Mesh>(val6);
			val6.vertices = Array.Empty<Vector3>();
			val6.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val7 = Own<SkinDefParams>(ScriptableObject.CreateInstance<SkinDefParams>());
			val7.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val7.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderer,
					mesh = val6,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val8 = Own<SkinDef>(ScriptableObject.CreateInstance<SkinDef>());
			((Object)val8).name = "EclipsePlaytestAcridE5GingerCat";
			val8.nameToken = "ECLIPSE_PLAYTEST_ACRID_E5_GINGER_CAT";
			LanguageAPI.Add(val8.nameToken, "Ginger Cat (Playtest)");
			val8.unlockableDef = null;
			val8.rootObject = modelPrefab;
			val8.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val8.skinDefParams = val7;
			val8.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			Own<Sprite>(val8.icon);
			SkinDef[] array = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			SkinDef[] skins = (SkinDef[])array.Clone();
			AdvancedSkinRegistry.Register(val5);
			registryCommitted = true;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val8, mesh);
			controller.skins = array;
			val3.skins = skins;
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E5_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=species_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E5_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared animal display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared animal display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E5_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			ReleaseUncommitted();
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridE6Animals/AcridE6.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
public sealed class AnimalContactConstraint : ISkinPoseConstraint
{
	private readonly MotionBank bank;

	private readonly int[][] chains;

	private readonly float[] floor;

	private readonly PoseMixer braceMixer;

	private readonly Pose[] braceBase;

	private readonly int body;

	private readonly int chest;

	public int CorrectedFeet { get; private set; }

	public AnimalContactConstraint(MotionBank bank)
	{
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Expected O, but got Unknown
		AnimalContactConstraint animalContactConstraint = this;
		this.bank = bank ?? throw new ArgumentNullException("bank");
		chains = (from prefix in new string[2] { "Fore", "Hind" }
			from side in new string[2] { "L", "R" }
			select new string[3] { "Upper", "Lower", "Foot" }.Select((string part) => Array.FindIndex(bank.Bones, (Bone b) => b.Name == prefix + part + side)).ToArray()).ToArray();
		if (chains.Any((int[] c) => c.Any((int i) => i < 0) || bank.Bones[c[1]].Parent != c[0] || bank.Bones[c[2]].Parent != c[1]))
		{
			throw new ArgumentException("Expected four two-segment limbs");
		}
		Pose[] rest = bank.Bones.Select((Bone b) => b.Rest).ToArray();
		floor = chains.Select((int[] c) => animalContactConstraint.World(rest, c[2]).Position.Z).ToArray();
		body = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "Body");
		chest = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "Chest");
		if (bank.SkinId.Contains("AcridE7") && bank.Find("slam").Tracks.Any((Track t) => t.Bone == animalContactConstraint.body))
		{
			braceMixer = new PoseMixer(bank, "idle");
			braceBase = (Pose[])(object)new Pose[bank.Bones.Length];
		}
	}

	private static float Dot(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
	}

	private static float Length(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (float)Math.Sqrt(Dot(v, v));
	}

	private static V3 Unit(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		float num = Length(v);
		if (!(num < 1E-08f))
		{
			return v * (1f / num);
		}
		return new V3(1f, 0f, 0f);
	}

	private static V3 Cross(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		return new V3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
	}

	private static V3 Rotate(Q4 q, V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		Q4 val = q * new Q4(v.X, v.Y, v.Z, 0f) * ((Q4)(ref q)).Inverse;
		return new V3(val.X, val.Y, val.Z);
	}

	private static Q4 FromTo(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		a = Unit(a);
		b = Unit(b);
		float num = Dot(a, b);
		if (num < -0.99999f)
		{
			V3 val = Unit(Cross(a, ((double)Math.Abs(a.X) < 0.8) ? new V3(1f, 0f, 0f) : new V3(0f, 1f, 0f)));
			return new Q4(val.X, val.Y, val.Z, 0f);
		}
		V3 val2 = Cross(a, b);
		Q4 val3 = new Q4(val2.X, val2.Y, val2.Z, 1f + num);
		return ((Q4)(ref val3)).Normalized();
	}

	private Pose World(Pose[] p, int i)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Pose val = p[i];
		int parent = bank.Bones[i].Parent;
		if (parent < 0)
		{
			return val;
		}
		Pose val2 = World(p, parent);
		V3 val3 = val2.Position + Rotate(val2.Rotation, val.Position);
		Q4 val4 = val2.Rotation * val.Rotation;
		return new Pose(val3, ((Q4)(ref val4)).Normalized(), new V3(1f, 1f, 1f));
	}

	private void Solve(Pose[] p, int[] c, Pose target)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: 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_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		Pose val = World(p, c[0]);
		Pose val2 = World(p, c[1]);
		V3 v = target.Position - val.Position;
		float num = Length(p[c[1]].Position);
		float num2 = Length(p[c[2]].Position);
		float num3 = Length(v);
		if (!(num3 > num + num2 + 0.0002f) && !(num3 < Math.Abs(num - num2) - 0.0002f))
		{
			float num4 = Math.Max(Math.Abs(num - num2) + 1E-05f, Math.Min(num + num2 - 1E-05f, num3));
			V3 val3 = Unit(v);
			V3 val4 = val2.Position - val.Position;
			val4 -= val3 * Dot(val4, val3);
			if (Length(val4) < 0.0001f)
			{
				val4 = Cross(val3, ((double)Math.Abs(val3.Z) < 0.8) ? new V3(0f, 0f, 1f) : new V3(0f, 1f, 0f));
			}
			val4 = Unit(val4);
			float num5 = (num * num + num4 * num4 - num2 * num2) / (2f * num4);
			V3 val5 = val.Position + val3 * num5 + val4 * (float)Math.Sqrt(Math.Max(0f, num * num - num5 * num5));
			V3 val6 = val.Position + val3 * num4;
			Q4 val7 = FromTo(Rotate(val.Rotation, p[c[1]].Position), val5 - val.Position) * val.Rotation;
			Q4 val8 = ((Q4)(ref val7)).Normalized();
			val7 = FromTo(Rotate(val2.Rotation, p[c[2]].Position), val6 - val5) * val2.Rotation;
			Q4 val9 = ((Q4)(ref val7)).Normalized();
			int parent = bank.Bones[c[0]].Parent;
			Q4 val10 = ((parent < 0) ? Q4.Identity : World(p, parent).Rotation);
			ref Pose reference = ref p[c[0]];
			val7 = ((Q4)(ref val10)).Inverse * val8;
			reference.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference2 = ref p[c[1]];
			val7 = ((Q4)(ref val8)).Inverse * val9;
			reference2.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference3 = ref p[c[2]];
			val7 = ((Q4)(ref val9)).Inverse * target.Rotation;
			reference3.Rotation = ((Q4)(ref val7)).Normalized();
			CorrectedFeet++;
		}
	}

	private static bool HornStrike(WeightedMotion s)
	{
		if (!(s.Clip.Id == "slash_left") && !(s.Clip.Id == "slash_right"))
		{
			return s.Clip.Id == "slam";
		}
		return true;
	}

	private void Brace(MotionLayer[] layers, Pose[] pose)
	{
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		if (braceMixer == null || !layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && HornStrike(s))))
		{
			return;
		}
		MotionLayer[] array = (from l in ((IEnumerable<MotionLayer>)layers).Select((Func<MotionLayer, MotionLayer>)((MotionLayer l) => new MotionLayer
			{
				Group = l.Group,
				Priority = l.Priority,
				Blend = l.Blend,
				BoneMask = l.BoneMask,
				Samples = l.Samples.Where((WeightedMotion s) => !HornStrike(s)).ToArray()
			}))
			where l.Samples.Length != 0
			select l).ToArray();
		braceMixer.Evaluate((IEnumerable<MotionLayer>)array, braceBase);
		Pose[] targets = chains.Select((int[] c) => World(braceBase, c[2])).ToArray();
		Pose desiredBody = pose[body];
		Pose desiredChest = pose[chest];
		Func<float, bool> func = delegate(float strength)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			pose[body] = Pose.Blend(braceBase[body], desiredBody, strength);
			pose[chest] = Pose.Blend(braceBase[chest], desiredChest, strength);
			for (int i = 0; i < chains.Length; i++)
			{
				int[] array4 = chains[i];
				float num10 = Length(targets[i].Position - World(pose, array4[0]).Position);
				float num11 = Length(pose[array4[1]].Position);
				float num12 = Length(pose[array4[2]].Position);
				if (num10 > num11 + num12 - 2E-05f || num10 < Math.Abs(num11 - num12) + 2E-05f)
				{
					return false;
				}
			}
			return true;
		};
		float num = 1f;
		if (!func(1f))
		{
			float num2 = 0f;
			float num3 = 1f;
			for (int num4 = 0; num4 < 12; num4++)
			{
				float num5 = (num2 + num3) * 0.5f;
				if (func(num5))
				{
					num2 = num5;
				}
				else
				{
					num3 = num5;
				}
			}
			num = num2;
			func(num);
		}
		int[][] array2 = chains;
		foreach (int[] array3 in array2)
		{
			foreach (int num8 in array3)
			{
				pose[num8] = braceBase[num8];
			}
		}
		if (num > 1E-05f)
		{
			for (int num9 = 0; num9 < chains.Length; num9++)
			{
				Solve(pose, chains[num9], targets[num9]);
			}
		}
	}

	public void Apply(MotionLayer[] layers, Pose[] pose, bool grounded)
	{
		//IL_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		CorrectedFeet = 0;
		if (layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && s.Clip.Id == "death")))
		{
			return;
		}
		Brace(layers, pose);
		if (!grounded)
		{
			return;
		}
		for (int num = 0; num < chains.Length; num++)
		{
			Pose val = World(pose, chains[num][2]);
			if (!(val.Position.Z >= floor[num] - 0.0001f))
			{
				val.Position.Z = floor[num];
				Solve(pose, chains[num], val);
			}
		}
	}
}
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE6
{
	[BepInPlugin("eclipseplaytest.acrid.e6", "Acrid - Squirrel (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Squirrel : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile normal;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e6";

		public const string Version = "0.1.3";

		public const string SkinId = "EclipsePlaytestAcridE6Squirrel";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static Squirrel instance;

		private string folder;

		private float deadline;

		private bool registered;

		private bool registryCommitted;

		private readonly List<Object> pendingObjects = new List<Object>();

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(Squirrel));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E6_REGISTRATION_BEGIN version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E6_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				(routine as IDisposable)?.Dispose();
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.ReleaseUncommitted();
				}
			}
		}

		private T Own<T>(T value) where T : Object
		{
			pendingObjects.Add((Object)(object)value);
			return value;
		}

		private void ReleaseUncommitted()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (registered || registryCommitted)
			{
				return;
			}
			registration?.Dispose();
			registration = null;
			foreach (AsyncOperationHandle retainedAsset in retainedAssets)
			{
				AsyncOperationHandle current = retainedAsset;
				if (((AsyncOperationHandle)(ref current)).IsValid())
				{
					Addressables.Release(current);
				}
			}
			retainedAssets.Clear();
			foreach (Object pendingObject in pendingObjects)
			{
				if (Object.op_Implicit(pendingObject))
				{
					Object.Destroy(pendingObject);
				}
			}
			pendingObjects.Clear();
		}

		private void ValidateTemplate(GameObject model)
		{
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			if (!Object.op_Implicit((Object)(object)model.GetComponent<Animator>()) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Original Croco template is required");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Animal asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid animal asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Animal asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Animal asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Animal requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration AnimalGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0132: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "HindFootL"),
				ContactCues = bank.Find("walk").Cues
			};
			string[] array = new string[6] { "walk", "run", "sprint", "backpedal", "strafe_left", "strafe_right" };
			foreach (string text in array)
			{
				float num2 = ((text == "run") ? 5.4f : ((text == "sprint") ? 7f : 4.4f));
				val.TravelPerCycle.Add(text, (text == "backpedal") ? new V3(0f, num2, 0f) : ((text == "strafe_left") ? new V3(num2, 0f, 0f) : ((text == "strafe_right") ? new V3(0f - num2, 0f, 0f) : new V3(0f, 0f - num2, 0f))));
				val.CyclesPerWorldMetre.Add(text, (text == "sprint") ? 0.2f : ((text == "run") ? 0.23f : 0.26f));
				val.ContactCuesByClip.Add(text, bank.Find(text).Cues);
			}
			val.MaximumCyclesPerSecond = 2.8;
			val.Acceleration = 10.0;
			val.Validate(bank);
			return val;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "animal-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE6Squirrel" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid animal asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE6Squirrel")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = AnimalGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE6Squirrel")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = Own<Mesh>(SkinMesh.Read((Stream)memoryStream2, bank));
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "SquirrelAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(albedo);
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid animal albedo");
			}
			mesh.RecalculateTangents();
			Texture2D normal = new Texture2D(2, 2, (TextureFormat)4, true, true)
			{
				name = "SquirrelNormal",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(normal);
			if (!ImageConversion.LoadImage(normal, ReadAsset(manifest.normal), false))
			{
				throw new InvalidDataException("Invalid animal normal map");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			Own<Texture2D>(icon);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid animal icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE6Squirrel"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			ValidateTemplate(modelPrefab);
			ValidateTemplate(displayModelPrefab);
			SkinnedMeshRenderer renderer = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh");
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE6Squirrel"
			};
			Own<Material>(val4);
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetTexture("_NormalTex", (Texture)(object)normal);
			val4.SetFloat("_NormalStrength", 0.1f);
			val4.SetFloat("_Smoothness", 0.09f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinDefinition val5 = new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreatePoseConstraint = (MotionBank motion) => (ISkinPoseConstraint)(object)new AnimalContactConstraint(motion),
				CreateAttachments = (SkinnedMeshRenderer val9, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(val9, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer val9) => (ISkinEffectDriver)new CrocoLeapCosmetics(val9),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer val9, MotionBank motion) => (ISkinMotionTiming)new CrocoModelGaitTiming(val9, motion, gait)
			};
			Mesh val6 = new Mesh
			{
				name = "EclipseAcridE6EmptySpines"
			};
			Own<Mesh>(val6);
			val6.vertices = Array.Empty<Vector3>();
			val6.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val7 = Own<SkinDefParams>(ScriptableObject.CreateInstance<SkinDefParams>());
			val7.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val7.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderer,
					mesh = val6,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val8 = Own<SkinDef>(ScriptableObject.CreateInstance<SkinDef>());
			((Object)val8).name = "EclipsePlaytestAcridE6Squirrel";
			val8.nameToken = "ECLIPSE_PLAYTEST_ACRID_E6_SQUIRREL";
			LanguageAPI.Add(val8.nameToken, "Squirrel (Playtest)");
			val8.unlockableDef = null;
			val8.rootObject = modelPrefab;
			val8.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val8.skinDefParams = val7;
			val8.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			Own<Sprite>(val8.icon);
			SkinDef[] array = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			SkinDef[] skins = (SkinDef[])array.Clone();
			AdvancedSkinRegistry.Register(val5);
			registryCommitted = true;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val8, mesh);
			controller.skins = array;
			val3.skins = skins;
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E6_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=species_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E6_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared animal display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared animal display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E6_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			ReleaseUncommitted();
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridE7Animals/AcridE7.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
public sealed class AnimalBraceTiming : ISkinMotionTiming, IDisposable, ISkinPresentationOffset
{
	private readonly ISkinMotionTiming inner;

	private readonly ISkinPresentationOffset presentation;

	private bool disposed;

	public Vector3 LocalPresentationOffset
	{
		get
		{
			//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)
			if (disposed || presentation == null)
			{
				return Vector3.zero;
			}
			return presentation.LocalPresentationOffset;
		}
	}

	public bool Restarted
	{
		get
		{
			if (!disposed && presentation != null)
			{
				return presentation.Restarted;
			}
			return false;
		}
	}

	public AnimalBraceTiming(SkinnedMeshRenderer renderer, MotionBank bank, GaitCalibration calibration)
		: this((ISkinMotionTiming)new CrocoModelGaitTiming(renderer, bank, calibration))
	{
	}//IL_0004: Unknown result type (might be due to invalid IL or missing references)
	//IL_000e: Expected O, but got Unknown


	internal AnimalBraceTiming(ISkinMotionTiming inner)
	{
		this.inner = inner ?? throw new ArgumentNullException("inner");
		presentation = (ISkinPresentationOffset)(object)((inner is ISkinPresentationOffset) ? inner : null);
	}

	private static bool HornStrike(WeightedMotion sample)
	{
		if (!(sample.Clip.Id == "slash_left") && !(sample.Clip.Id == "slash_right"))
		{
			return sample.Clip.Id == "slam";
		}
		return true;
	}

	private static MotionLayer Underlying(MotionLayer layer)
	{
		//IL_0000: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		return new MotionLayer
		{
			Group = layer.Group,
			Priority = layer.Priority,
			Blend = layer.Blend,
			BoneMask = layer.BoneMask,
			Samples = layer.Samples.Where((WeightedMotion sample) => !HornStrike(sample)).ToArray()
		};
	}

	public void Retime(MotionLayer[] composed, IEnumerable<NativeMotionCandidate> observed)
	{
		if (!disposed)
		{
			MotionLayer[] array = (from layer in composed.Select(Underlying)
				where layer.Samples.Length != 0
				select layer).ToArray();
			NativeMotionCandidate[] array2 = (from candidate in observed.Select((Func<NativeMotionCandidate, NativeMotionCandidate>)((NativeMotionCandidate candidate) => new NativeMotionCandidate
				{
					SourceLayer = candidate.SourceLayer,
					SourceRank = candidate.SourceRank,
					Motion = Underlying(candidate.Motion)
				}))
				where candidate.Motion.Samples.Length != 0
				select candidate).ToArray();
			inner.Retime(array, (IEnumerable<NativeMotionCandidate>)array2);
		}
	}

	public bool OwnsCues(MotionClip clip)
	{
		if (!disposed)
		{
			return inner.OwnsCues(clip);
		}
		return false;
	}

	public void AdvanceCues(Action<string> emit)
	{
		if (!disposed)
		{
			inner.AdvanceCues(emit);
		}
	}

	public void ResetPresentation()
	{
		if (!disposed)
		{
			ISkinPresentationOffset obj = presentation;
			if (obj != null)
			{
				obj.ResetPresentation();
			}
		}
	}

	public void Dispose()
	{
		if (!disposed)
		{
			disposed = true;
			((IDisposable)inner).Dispose();
		}
	}
}
public sealed class AnimalContactConstraint : ISkinPoseConstraint
{
	private readonly MotionBank bank;

	private readonly int[][] chains;

	private readonly float[] floor;

	private readonly PoseMixer braceMixer;

	private readonly Pose[] braceBase;

	private readonly int body;

	private readonly int chest;

	public int CorrectedFeet { get; private set; }

	public AnimalContactConstraint(MotionBank bank)
	{
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Expected O, but got Unknown
		AnimalContactConstraint animalContactConstraint = this;
		this.bank = bank ?? throw new ArgumentNullException("bank");
		chains = (from prefix in new string[2] { "Fore", "Hind" }
			from side in new string[2] { "L", "R" }
			select new string[3] { "Upper", "Lower", "Foot" }.Select((string part) => Array.FindIndex(bank.Bones, (Bone b) => b.Name == prefix + part + side)).ToArray()).ToArray();
		if (chains.Any((int[] c) => c.Any((int i) => i < 0) || bank.Bones[c[1]].Parent != c[0] || bank.Bones[c[2]].Parent != c[1]))
		{
			throw new ArgumentException("Expected four two-segment limbs");
		}
		Pose[] rest = bank.Bones.Select((Bone b) => b.Rest).ToArray();
		floor = chains.Select((int[] c) => animalContactConstraint.World(rest, c[2]).Position.Z).ToArray();
		body = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "Body");
		chest = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "Chest");
		if (bank.SkinId.Contains("AcridE7") && bank.Find("slam").Tracks.Any((Track t) => t.Bone == animalContactConstraint.body))
		{
			braceMixer = new PoseMixer(bank, "idle");
			braceBase = (Pose[])(object)new Pose[bank.Bones.Length];
		}
	}

	private static float Dot(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
	}

	private static float Length(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (float)Math.Sqrt(Dot(v, v));
	}

	private static V3 Unit(V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		float num = Length(v);
		if (!(num < 1E-08f))
		{
			return v * (1f / num);
		}
		return new V3(1f, 0f, 0f);
	}

	private static V3 Cross(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		return new V3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
	}

	private static V3 Rotate(Q4 q, V3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		Q4 val = q * new Q4(v.X, v.Y, v.Z, 0f) * ((Q4)(ref q)).Inverse;
		return new V3(val.X, val.Y, val.Z);
	}

	private static Q4 FromTo(V3 a, V3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		a = Unit(a);
		b = Unit(b);
		float num = Dot(a, b);
		if (num < -0.99999f)
		{
			V3 val = Unit(Cross(a, ((double)Math.Abs(a.X) < 0.8) ? new V3(1f, 0f, 0f) : new V3(0f, 1f, 0f)));
			return new Q4(val.X, val.Y, val.Z, 0f);
		}
		V3 val2 = Cross(a, b);
		Q4 val3 = new Q4(val2.X, val2.Y, val2.Z, 1f + num);
		return ((Q4)(ref val3)).Normalized();
	}

	private Pose World(Pose[] p, int i)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Pose val = p[i];
		int parent = bank.Bones[i].Parent;
		if (parent < 0)
		{
			return val;
		}
		Pose val2 = World(p, parent);
		V3 val3 = val2.Position + Rotate(val2.Rotation, val.Position);
		Q4 val4 = val2.Rotation * val.Rotation;
		return new Pose(val3, ((Q4)(ref val4)).Normalized(), new V3(1f, 1f, 1f));
	}

	private void Solve(Pose[] p, int[] c, Pose target)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: 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_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		Pose val = World(p, c[0]);
		Pose val2 = World(p, c[1]);
		V3 v = target.Position - val.Position;
		float num = Length(p[c[1]].Position);
		float num2 = Length(p[c[2]].Position);
		float num3 = Length(v);
		if (!(num3 > num + num2 + 0.0002f) && !(num3 < Math.Abs(num - num2) - 0.0002f))
		{
			float num4 = Math.Max(Math.Abs(num - num2) + 1E-05f, Math.Min(num + num2 - 1E-05f, num3));
			V3 val3 = Unit(v);
			V3 val4 = val2.Position - val.Position;
			val4 -= val3 * Dot(val4, val3);
			if (Length(val4) < 0.0001f)
			{
				val4 = Cross(val3, ((double)Math.Abs(val3.Z) < 0.8) ? new V3(0f, 0f, 1f) : new V3(0f, 1f, 0f));
			}
			val4 = Unit(val4);
			float num5 = (num * num + num4 * num4 - num2 * num2) / (2f * num4);
			V3 val5 = val.Position + val3 * num5 + val4 * (float)Math.Sqrt(Math.Max(0f, num * num - num5 * num5));
			V3 val6 = val.Position + val3 * num4;
			Q4 val7 = FromTo(Rotate(val.Rotation, p[c[1]].Position), val5 - val.Position) * val.Rotation;
			Q4 val8 = ((Q4)(ref val7)).Normalized();
			val7 = FromTo(Rotate(val2.Rotation, p[c[2]].Position), val6 - val5) * val2.Rotation;
			Q4 val9 = ((Q4)(ref val7)).Normalized();
			int parent = bank.Bones[c[0]].Parent;
			Q4 val10 = ((parent < 0) ? Q4.Identity : World(p, parent).Rotation);
			ref Pose reference = ref p[c[0]];
			val7 = ((Q4)(ref val10)).Inverse * val8;
			reference.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference2 = ref p[c[1]];
			val7 = ((Q4)(ref val8)).Inverse * val9;
			reference2.Rotation = ((Q4)(ref val7)).Normalized();
			ref Pose reference3 = ref p[c[2]];
			val7 = ((Q4)(ref val9)).Inverse * target.Rotation;
			reference3.Rotation = ((Q4)(ref val7)).Normalized();
			CorrectedFeet++;
		}
	}

	private static bool HornStrike(WeightedMotion s)
	{
		if (!(s.Clip.Id == "slash_left") && !(s.Clip.Id == "slash_right"))
		{
			return s.Clip.Id == "slam";
		}
		return true;
	}

	private void Brace(MotionLayer[] layers, Pose[] pose)
	{
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		if (braceMixer == null || !layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && HornStrike(s))))
		{
			return;
		}
		MotionLayer[] array = (from l in ((IEnumerable<MotionLayer>)layers).Select((Func<MotionLayer, MotionLayer>)((MotionLayer l) => new MotionLayer
			{
				Group = l.Group,
				Priority = l.Priority,
				Blend = l.Blend,
				BoneMask = l.BoneMask,
				Samples = l.Samples.Where((WeightedMotion s) => !HornStrike(s)).ToArray()
			}))
			where l.Samples.Length != 0
			select l).ToArray();
		braceMixer.Evaluate((IEnumerable<MotionLayer>)array, braceBase);
		Pose[] targets = chains.Select((int[] c) => World(braceBase, c[2])).ToArray();
		Pose desiredBody = pose[body];
		Pose desiredChest = pose[chest];
		Func<float, bool> func = delegate(float strength)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			pose[body] = Pose.Blend(braceBase[body], desiredBody, strength);
			pose[chest] = Pose.Blend(braceBase[chest], desiredChest, strength);
			for (int i = 0; i < chains.Length; i++)
			{
				int[] array4 = chains[i];
				float num10 = Length(targets[i].Position - World(pose, array4[0]).Position);
				float num11 = Length(pose[array4[1]].Position);
				float num12 = Length(pose[array4[2]].Position);
				if (num10 > num11 + num12 - 2E-05f || num10 < Math.Abs(num11 - num12) + 2E-05f)
				{
					return false;
				}
			}
			return true;
		};
		float num = 1f;
		if (!func(1f))
		{
			float num2 = 0f;
			float num3 = 1f;
			for (int num4 = 0; num4 < 12; num4++)
			{
				float num5 = (num2 + num3) * 0.5f;
				if (func(num5))
				{
					num2 = num5;
				}
				else
				{
					num3 = num5;
				}
			}
			num = num2;
			func(num);
		}
		int[][] array2 = chains;
		foreach (int[] array3 in array2)
		{
			foreach (int num8 in array3)
			{
				pose[num8] = braceBase[num8];
			}
		}
		if (num > 1E-05f)
		{
			for (int num9 = 0; num9 < chains.Length; num9++)
			{
				Solve(pose, chains[num9], targets[num9]);
			}
		}
	}

	public void Apply(MotionLayer[] layers, Pose[] pose, bool grounded)
	{
		//IL_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		CorrectedFeet = 0;
		if (layers.Any((MotionLayer l) => l.Samples.Any((WeightedMotion s) => s.Weight > 0.001f && s.Clip.Id == "death")))
		{
			return;
		}
		Brace(layers, pose);
		if (!grounded)
		{
			return;
		}
		for (int num = 0; num < chains.Length; num++)
		{
			Pose val = World(pose, chains[num][2]);
			if (!(val.Position.Z >= floor[num] - 0.0001f))
			{
				val.Position.Z = floor[num];
				Solve(pose, chains[num], val);
			}
		}
	}
}
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE7
{
	[BepInPlugin("eclipseplaytest.acrid.e7", "Acrid - Goat (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Goat : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile normal;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e7";

		public const string Version = "0.1.3";

		public const string SkinId = "EclipsePlaytestAcridE7Goat";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static Goat instance;

		private string folder;

		private float deadline;

		private bool registered;

		private bool registryCommitted;

		private readonly List<Object> pendingObjects = new List<Object>();

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(Goat));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E7_REGISTRATION_BEGIN version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E7_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				(routine as IDisposable)?.Dispose();
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.ReleaseUncommitted();
				}
			}
		}

		private T Own<T>(T value) where T : Object
		{
			pendingObjects.Add((Object)(object)value);
			return value;
		}

		private void ReleaseUncommitted()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (registered || registryCommitted)
			{
				return;
			}
			registration?.Dispose();
			registration = null;
			foreach (AsyncOperationHandle retainedAsset in retainedAssets)
			{
				AsyncOperationHandle current = retainedAsset;
				if (((AsyncOperationHandle)(ref current)).IsValid())
				{
					Addressables.Release(current);
				}
			}
			retainedAssets.Clear();
			foreach (Object pendingObject in pendingObjects)
			{
				if (Object.op_Implicit(pendingObject))
				{
					Object.Destroy(pendingObject);
				}
			}
			pendingObjects.Clear();
		}

		private void ValidateTemplate(GameObject model)
		{
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			if (!Object.op_Implicit((Object)(object)model.GetComponent<Animator>()) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Original Croco template is required");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Animal asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid animal asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Animal asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Animal asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Animal requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration AnimalGait(MotionBank bank)
		{
			//IL_0000: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0132: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			GaitCalibration val = new GaitCalibration
			{
				ReferenceFoot = Array.FindIndex(bank.Bones, (Bone b) => b.Name == "HindFootL"),
				ContactCues = bank.Find("walk").Cues
			};
			string[] array = new string[6] { "walk", "run", "sprint", "backpedal", "strafe_left", "strafe_right" };
			foreach (string text in array)
			{
				float num2 = ((text == "run") ? 6.8f : ((text == "sprint") ? 8.4f : 4.4f));
				val.TravelPerCycle.Add(text, (text == "backpedal") ? new V3(0f, num2, 0f) : ((text == "strafe_left") ? new V3(num2, 0f, 0f) : ((text == "strafe_right") ? new V3(0f - num2, 0f, 0f) : new V3(0f, 0f - num2, 0f))));
				val.CyclesPerWorldMetre.Add(text, (text == "sprint") ? 0.2f : ((text == "run") ? 0.23f : 0.26f));
				val.ContactCuesByClip.Add(text, bank.Find(text).Cues);
			}
			val.MaximumCyclesPerSecond = 2.8;
			val.Acceleration = 10.0;
			val.Validate(bank);
			return val;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "animal-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE7Goat" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid animal asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE7Goat")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			GaitCalibration gait = AnimalGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE7Goat")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = Own<Mesh>(SkinMesh.Read((Stream)memoryStream2, bank));
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "GoatAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(albedo);
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid animal albedo");
			}
			mesh.RecalculateTangents();
			Texture2D normal = new Texture2D(2, 2, (TextureFormat)4, true, true)
			{
				name = "GoatNormal",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(normal);
			if (!ImageConversion.LoadImage(normal, ReadAsset(manifest.normal), false))
			{
				throw new InvalidDataException("Invalid animal normal map");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			Own<Texture2D>(icon);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid animal icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE7Goat"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			ValidateTemplate(modelPrefab);
			ValidateTemplate(displayModelPrefab);
			SkinnedMeshRenderer renderer = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh");
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE7Goat"
			};
			Own<Material>(val4);
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetTexture("_NormalTex", (Texture)(object)normal);
			val4.SetFloat("_NormalStrength", 0.24f);
			val4.SetFloat("_Smoothness", 0.09f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0f);
			val4.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinDefinition val5 = new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreatePoseConstraint = (MotionBank motion) => (ISkinPoseConstraint)(object)new AnimalContactConstraint(motion),
				CreateAttachments = (SkinnedMeshRenderer val9, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(val9, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer val9) => (ISkinEffectDriver)new CrocoLeapCosmetics(val9),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true),
				CreateMotionTiming = (SkinnedMeshRenderer renderer2, MotionBank motion) => (ISkinMotionTiming)(object)new AnimalBraceTiming(renderer2, motion, gait)
			};
			Mesh val6 = new Mesh
			{
				name = "EclipseAcridE7EmptySpines"
			};
			Own<Mesh>(val6);
			val6.vertices = Array.Empty<Vector3>();
			val6.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val7 = Own<SkinDefParams>(ScriptableObject.CreateInstance<SkinDefParams>());
			val7.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val7.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderer,
					mesh = val6,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val8 = Own<SkinDef>(ScriptableObject.CreateInstance<SkinDef>());
			((Object)val8).name = "EclipsePlaytestAcridE7Goat";
			val8.nameToken = "ECLIPSE_PLAYTEST_ACRID_E7_GOAT";
			LanguageAPI.Add(val8.nameToken, "Goat (Playtest)");
			val8.unlockableDef = null;
			val8.rootObject = modelPrefab;
			val8.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val8.skinDefParams = val7;
			val8.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			Own<Sprite>(val8.icon);
			SkinDef[] array = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			SkinDef[] skins = (SkinDef[])array.Clone();
			AdvancedSkinRegistry.Register(val5);
			registryCommitted = true;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val8, mesh);
			controller.skins = array;
			val3.skins = skins;
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E7_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=species_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E7_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared animal display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared animal display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E7_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			ReleaseUncommitted();
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}

BepInEx/plugins/AcridE8Animals/AcridE8.dll

Decompiled a week 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.Security.Cryptography;
using System.Text;
using BepInEx;
using Eclipse.AdvancedSkins;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: AssemblyVersion("0.0.0.0")]
namespace EclipseSkinRuntimeFix
{
	internal static class NativeRenderers
	{
		private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal)
		{
			"mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef",
			"mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh",
			"mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead",
			"mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh"
		};

		public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			return owner.gameObject.GetSkinRenderers<T>(inactive, parameters);
		}

		public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive);
			CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>();
			ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null);
			HashSet<Renderer> skinRefs = new HashSet<Renderer>();
			SkinDefParams val3 = parameters;
			if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0]))
			{
				val3 = val2.skins[0].skinDefParams;
			}
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (val3.rendererInfos != null)
				{
					RendererInfo[] rendererInfos = val3.rendererInfos;
					foreach (RendererInfo val4 in rendererInfos)
					{
						if (Object.op_Implicit((Object)(object)val4.renderer))
						{
							skinRefs.Add(val4.renderer);
						}
					}
				}
				if (val3.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = val3.meshReplacements;
					foreach (MeshReplacement val5 in meshReplacements)
					{
						if (Object.op_Implicit((Object)(object)val5.renderer))
						{
							skinRefs.Add(val5.renderer);
						}
					}
				}
			}
			HashSet<Renderer> modelRefs = new HashSet<Renderer>();
			if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null)
			{
				RendererInfo[] rendererInfos = val.baseRendererInfos;
				foreach (RendererInfo val6 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val6.renderer))
					{
						modelRefs.Add(val6.renderer);
					}
				}
			}
			return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform)));
		}

		internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null)
		{
			HashSet<T> hashSet = new HashSet<T>();
			if (contract == null)
			{
				contract = (T x) => false;
			}
			bool flag = found.Any(skin) || found.Any(model) || found.Any(contract);
			foreach (IGrouping<string, T> item in found.GroupBy(name))
			{
				T[] array = item.ToArray();
				if (array.Length == 1)
				{
					if (!flag || skin(array[0]) || model(array[0]) || contract(array[0]))
					{
						hashSet.Add(array[0]);
					}
					continue;
				}
				T[] array2 = array.Where(skin).ToArray();
				T[] array3 = array.Where(model).ToArray();
				T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray()));
				if (array2.Length == 0 && array3.Length == 0)
				{
					T[] array5 = array.Where(contract).ToArray();
					if (array5.Length != 0)
					{
						if (array5.Length != 1)
						{
							throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path)));
						}
						hashSet.Add(array5[0]);
						Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0])));
						continue;
					}
				}
				if (array2.Length == 0 && array3.Length == 0 && flag)
				{
					Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length));
					continue;
				}
				if (array4.Length != 1)
				{
					throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length);
				}
				hashSet.Add(array4[0]);
				Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1)));
			}
			return found.Where(hashSet.Contains).ToArray();
		}

		internal static bool IsKnownNativePath(string path)
		{
			if (path == null)
			{
				return false;
			}
			int num = path.IndexOf('/');
			if (num < 0)
			{
				return false;
			}
			string text = path.Substring(0, num);
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - 7);
			}
			return NativePaths.Contains(text + path.Substring(num));
		}

		private static string Path(Transform t, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while (Object.op_Implicit((Object)(object)val))
			{
				list.Add(((Object)val).name);
				if ((Object)(object)val == (Object)(object)root)
				{
					break;
				}
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class NativeParameterBinding
	{
		private static string CrocoPath(Renderer renderer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return null;
			}
			List<string> list = new List<string>();
			Transform val = ((Component)renderer).transform;
			while (Object.op_Implicit((Object)(object)val))
			{
				string name = ((Object)val).name;
				if (name == "mdlCroco" || name == "mdlCroco(Clone)")
				{
					list.Add("mdlCroco");
					list.Reverse();
					string text = string.Join("/", list);
					if (!(text == "mdlCroco/CrocoMesh") && !(text == "mdlCroco/CrocoSpineMesh"))
					{
						return null;
					}
					return text;
				}
				list.Add(name);
				val = val.parent;
			}
			return null;
		}

		private static int Index<T>(T[] values, Func<T, Renderer> renderer, Renderer target, bool required)
		{
			if (!Object.op_Implicit((Object)(object)target))
			{
				throw new ArgumentException("Native renderer target missing");
			}
			values = values ?? new T[0];
			int[] array = (from i in Enumerable.Range(0, values.Length)
				where (Object)(object)renderer(values[i]) == (Object)(object)target
				select i).ToArray();
			if (array.Length == 0)
			{
				string path = CrocoPath(target);
				if (path != null)
				{
					array = (from i in Enumerable.Range(0, values.Length)
						where CrocoPath(renderer(values[i])) == path
						select i).ToArray();
				}
			}
			if (array.Length > 1)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_AMBIGUOUS target=" + ((Object)target).name);
			}
			if (array.Length == 0 && required)
			{
				throw new InvalidOperationException("ACRID_NATIVE_PARAMETER_MISSING target=" + ((Object)target).name);
			}
			if (array.Length != 1)
			{
				return -1;
			}
			return array[0];
		}

		public static RendererInfo RendererInfo(SkinDefParams parameters, Renderer target)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.rendererInfos, (RendererInfo x) => x.renderer, target, required: true);
			RendererInfo result = parameters.rendererInfos[num];
			result.renderer = target;
			return result;
		}

		public static MeshReplacement MeshReplacement(SkinDefParams parameters, Renderer target)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new ArgumentNullException("parameters");
			}
			int num = Index(parameters.meshReplacements, (MeshReplacement x) => x.renderer, target, required: false);
			if (num < 0)
			{
				return default(MeshReplacement);
			}
			MeshReplacement result = parameters.meshReplacements[num];
			result.renderer = target;
			return result;
		}
	}
}
namespace EclipsePlaytestAcridE8
{
	[BepInPlugin("eclipseplaytest.acrid.e8", "Acrid - Abyssal Angler (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class AbyssalAngler : BaseUnityPlugin
	{
		[Serializable]
		public sealed class AssetFile
		{
			public string file;

			public string sha256;
		}

		[Serializable]
		public sealed class AssetManifest
		{
			public int schema;

			public string skinId;

			public string revision;

			public AssetFile mesh;

			public AssetFile motion;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile normal;

			public AssetFile attachments;

			public AssetFile icon;

			public string[] nativeBoneNames;
		}

		[Serializable]
		public sealed class AttachmentsFile
		{
			public int schema;

			public string skinId;

			public SkinItemAttachmentRule[] rules;
		}

		public const string Guid = "eclipseplaytest.acrid.e8";

		public const string Version = "0.1.3";

		public const string SkinId = "EclipsePlaytestAcridE8AbyssalAngler";

		private SkinDefParams nativeParameters;

		private string registrationStage = "not-started";

		private static AbyssalAngler instance;

		private string folder;

		private float deadline;

		private bool registered;

		private bool registryCommitted;

		private readonly List<Object> pendingObjects = new List<Object>();

		private GameObject modelPrefab;

		private GameObject displayModelPrefab;

		private Mesh nativeMesh;

		private Material nativeMaterial;

		private AssetManifest manifest;

		private IDisposable registration;

		private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>();

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(AbyssalAngler));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			((BaseUnityPlugin)instance).Logger.LogInfo((object)("ACRID_E8_REGISTRATION_BEGIN version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location));
			IEnumerator routine = instance.Register();
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = routine.MoveNext();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)instance).Logger.LogError((object)("ACRID_E8_REGISTRATION_FAILED stage=" + instance.registrationStage + " version=0.1.3 location=" + ((BaseUnityPlugin)instance).Info.Location + " " + ex));
						break;
					}
					if (flag)
					{
						yield return routine.Current;
						continue;
					}
					break;
				}
			}
			finally
			{
				(routine as IDisposable)?.Dispose();
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.ReleaseUncommitted();
				}
			}
		}

		private T Own<T>(T value) where T : Object
		{
			pendingObjects.Add((Object)(object)value);
			return value;
		}

		private void ReleaseUncommitted()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (registered || registryCommitted)
			{
				return;
			}
			registration?.Dispose();
			registration = null;
			foreach (AsyncOperationHandle retainedAsset in retainedAssets)
			{
				AsyncOperationHandle current = retainedAsset;
				if (((AsyncOperationHandle)(ref current)).IsValid())
				{
					Addressables.Release(current);
				}
			}
			retainedAssets.Clear();
			foreach (Object pendingObject in pendingObjects)
			{
				if (Object.op_Implicit(pendingObject))
				{
					Object.Destroy(pendingObject);
				}
			}
			pendingObjects.Clear();
		}

		private void ValidateTemplate(GameObject model)
		{
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			if (!Object.op_Implicit((Object)(object)model.GetComponent<Animator>()) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Original Croco template is required");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
		}

		private void CheckDeadline()
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Animal asset loading timed out; other startup work continues.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.file.Contains("..") || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid animal asset manifest entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Animal asset too large");
			}
			byte[] array = File.ReadAllBytes(text);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256)
			{
				throw new InvalidDataException("Animal asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private void PrepareTemplate(GameObject model)
		{
			AdvancedSkinModel component = model.GetComponent<AdvancedSkinModel>();
			if (Object.op_Implicit((Object)(object)component) && component.HasNativeSnapshot)
			{
				component.Prepare();
				return;
			}
			SkinnedMeshRenderer val = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, nativeParameters).Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			Animator component2 = model.GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component2) || val.bones.Length != manifest.nativeBoneNames.Length)
			{
				throw new InvalidOperationException("Animal requires the original Croco skeleton");
			}
			for (int num = 0; num < val.bones.Length; num++)
			{
				if (!Object.op_Implicit((Object)(object)val.bones[num]) || ((Object)val.bones[num]).name != manifest.nativeBoneNames[num])
				{
					throw new InvalidOperationException("Native bone slot mismatch " + num);
				}
			}
			AdvancedSkinModel val2 = model.GetComponent<AdvancedSkinModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = model.AddComponent<AdvancedSkinModel>();
			}
			val2.CaptureNativeTemplate(val, component2, nativeMesh, (Material[])(object)new Material[1] { nativeMaterial });
			val2.Prepare();
		}

		private static GaitCalibration AnimalGait(MotionBank bank)
		{
			return null;
		}

		private IEnumerator Register()
		{
			registrationStage = "asset-manifest";
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "animal-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "EclipsePlaytestAcridE8AbyssalAngler" || string.IsNullOrWhiteSpace(manifest.revision) || manifest.nativeBoneNames == null || manifest.nativeBoneNames.Length != 94)
			{
				throw new InvalidDataException("Invalid animal asset identity");
			}
			registrationStage = "asset-decode";
			MotionBank bank;
			using (MemoryStream memoryStream = new MemoryStream(ReadAsset(manifest.motion), writable: false))
			{
				bank = MotionBank.Read((Stream)memoryStream);
			}
			if (bank.SkinId != "EclipsePlaytestAcridE8AbyssalAngler")
			{
				throw new InvalidDataException("Motion identity mismatch");
			}
			bank.Find("idle");
			CrocoStateMotionSource.ValidateBank(bank);
			AnimalGait(bank);
			AttachmentsFile attachmentsFile = JsonUtility.FromJson<AttachmentsFile>(Encoding.UTF8.GetString(ReadAsset(manifest.attachments)));
			if (attachmentsFile == null || attachmentsFile.schema != 1 || attachmentsFile.skinId != "EclipsePlaytestAcridE8AbyssalAngler")
			{
				throw new InvalidDataException("Attachment profile identity mismatch");
			}
			SkinItemAttachmentProfile attachmentProfile = new SkinItemAttachmentProfile((IEnumerable<SkinItemAttachmentRule>)attachmentsFile.rules, bank);
			Mesh mesh;
			using (MemoryStream memoryStream2 = new MemoryStream(ReadAsset(manifest.mesh), writable: false))
			{
				mesh = Own<Mesh>(SkinMesh.Read((Stream)memoryStream2, bank));
			}
			Texture2D albedo = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "AbyssalAnglerAlbedo",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(albedo);
			if (!ImageConversion.LoadImage(albedo, ReadAsset(manifest.albedo), false))
			{
				throw new InvalidDataException("Invalid animal albedo");
			}
			mesh.RecalculateTangents();
			Texture2D normal = new Texture2D(2, 2, (TextureFormat)4, true, true)
			{
				name = "AbyssalAnglerNormal",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(normal);
			if (!ImageConversion.LoadImage(normal, ReadAsset(manifest.normal), false))
			{
				throw new InvalidDataException("Invalid animal normal map");
			}
			Texture2D emission = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = "AbyssalAnglerLureEmission",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			Own<Texture2D>(emission);
			if (!ImageConversion.LoadImage(emission, ReadAsset(manifest.emission), false))
			{
				throw new InvalidDataException("Invalid lure emission map");
			}
			Texture2D icon = new Texture2D(2, 2, (TextureFormat)4, false, false);
			Own<Texture2D>(icon);
			if (!ImageConversion.LoadImage(icon, ReadAsset(manifest.icon), false))
			{
				throw new InvalidDataException("Invalid animal icon");
			}
			registrationStage = "native-body";
			GameObject body = BodyCatalog.FindBodyPrefab("CrocoBody");
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("Croco body unavailable");
			}
			modelPrefab = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0)
			{
				throw new InvalidOperationException("Native Croco skins unavailable");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "EclipsePlaytestAcridE8AbyssalAngler"))
			{
				yield break;
			}
			registrationStage = "native-parameters";
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams parameters = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)parameters) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op));
				while (!op.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				parameters = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)parameters))
			{
				throw new InvalidOperationException("Native skin parameters unavailable");
			}
			nativeParameters = parameters;
			registrationStage = "native-renderer-binding";
			SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, parameters);
			SkinnedMeshRenderer target = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoMesh");
			MeshReplacement val = NativeParameterBinding.MeshReplacement(parameters, (Renderer)(object)target);
			nativeMesh = val.mesh;
			if (!Object.op_Implicit((Object)(object)nativeMesh) && val.meshAddress != null && ((AssetReference)val.meshAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
				while (!op2.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMesh = op2.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh))
			{
				nativeMesh = target.sharedMesh;
			}
			if (!Object.op_Implicit((Object)(object)nativeMesh) || nativeMesh.bindposes.Length != 94)
			{
				throw new InvalidOperationException("Native fallback mesh invalid");
			}
			RendererInfo info = NativeParameterBinding.RendererInfo(parameters, (Renderer)(object)target);
			nativeMaterial = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)nativeMaterial) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3));
				while (!op3.IsDone)
				{
					CheckDeadline();
					yield return null;
				}
				nativeMaterial = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)nativeMaterial) || !Object.op_Implicit((Object)(object)nativeMaterial.shader))
			{
				throw new InvalidOperationException("Native fallback material invalid");
			}
			registrationStage = "display-template";
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(body);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				throw new InvalidOperationException("Croco display unavailable");
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				throw new InvalidOperationException("Croco display model unavailable");
			}
			displayModelPrefab = ((Component)componentInChildren).gameObject;
			ValidateTemplate(modelPrefab);
			ValidateTemplate(displayModelPrefab);
			SkinnedMeshRenderer renderer = renderers.Single((SkinnedMeshRenderer r) => ((Object)r).name == "CrocoSpineMesh");
			PrepareTemplate(modelPrefab);
			PrepareTemplate(displayModelPrefab);
			ModelSkinController val3 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
			Material val4 = new Material(nativeMaterial)
			{
				name = "matEclipseAcridE8AbyssalAngler"
			};
			Own<Material>(val4);
			val4.SetTexture("_MainTex", (Texture)(object)albedo);
			val4.SetColor("_Color", Color.white);
			val4.SetTexture("_NormalTex", (Texture)(object)normal);
			val4.SetFloat("_NormalStrength", 0.28f);
			val4.SetFloat("_Smoothness", 0.34f);
			val4.SetFloat("_SpecularStrength", 0.15f);
			val4.SetFloat("_SpecularExponent", 8f);
			val4.SetFloat("_EmPower", 0.65f);
			val4.SetTexture("_EmTex", (Texture)(object)emission);
			val4.DisableKeyword("FLOWMAP");
			val4.SetFloat("_FlowmapOn", 0f);
			val4.SetFloat("_FlowEmissionStrength", 0f);
			val4.DisableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 0f);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			registrationStage = "skin-definition";
			AdvancedSkinDefinition val5 = new AdvancedSkinDefinition
			{
				Mesh = mesh,
				Motion = bank,
				FallbackClip = "idle",
				AirTransitionSeconds = 0.16f,
				CreateAttachments = (SkinnedMeshRenderer val9, Func<string, Transform> anchor) => (ISkinAttachmentDriver)new NativeSkinItemAttachments(val9, anchor, attachmentProfile),
				CreateEffects = (SkinnedMeshRenderer val9) => (ISkinEffectDriver)new CrocoLeapCosmetics(val9),
				CreateMotionSource = (Animator animator, MotionBank motion) => (ISkinMotionSource)new CrocoModelMotionSource(animator, motion, true)
			};
			Mesh val6 = new Mesh
			{
				name = "EclipseAcridE8EmptySpines"
			};
			Own<Mesh>(val6);
			val6.vertices = Array.Empty<Vector3>();
			val6.triangles = Array.Empty<int>();
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val7 = Own<SkinDefParams>(ScriptableObject.CreateInstance<SkinDefParams>());
			val7.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { info };
			val7.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)renderer,
					mesh = val6,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			SkinDef val8 = Own<SkinDef>(ScriptableObject.CreateInstance<SkinDef>());
			((Object)val8).name = "EclipsePlaytestAcridE8AbyssalAngler";
			val8.nameToken = "ECLIPSE_PLAYTEST_ACRID_E8_ABYSSAL_ANGLER";
			LanguageAPI.Add(val8.nameToken, "Abyssal Angler (Playtest)");
			val8.unlockableDef = null;
			val8.rootObject = modelPrefab;
			val8.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			val8.skinDefParams = val7;
			val8.icon = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f));
			Own<Sprite>(val8.icon);
			SkinDef[] array = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			SkinDef[] skins = (SkinDef[])array.Clone();
			AdvancedSkinRegistry.Register(val5);
			registryCommitted = true;
			registrationStage = "publish";
			registration = AdvancedSkinApplications.Register(val8, mesh);
			controller.skins = array;
			val3.skins = skins;
			registered = true;
			registrationStage = "registered";
			LogSkinInventory();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E8_REGISTERED revision=" + manifest.revision + " customBones=" + bank.Bones.Length + " unlocked=true audio=not_integrated items=species_profile_candidate"));
		}

		private void LogSkinInventory()
		{
			if (Object.op_Implicit((Object)(object)modelPrefab))
			{
				ModelSkinController component = modelPrefab.GetComponent<ModelSkinController>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ACRID_E8_CATALOG stage=" + registrationStage + " skins=" + string.Join(";", from s in (Object.op_Implicit((Object)(object)component) && component.skins != null) ? ((IEnumerable<SkinDef>)component.skins) : ((IEnumerable<SkinDef>)Array.Empty<SkinDef>())
					where Object.op_Implicit((Object)(object)s)
					select ((Object)s).name)));
			}
		}

		private void SyncDisplaySkins()
		{
			LogSkinInventory();
			if (!registered)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)displayModelPrefab))
				{
					throw new InvalidOperationException("Prepared animal display was destroyed");
				}
				PrepareTemplate(displayModelPrefab);
				ModelSkinController component = displayModelPrefab.GetComponent<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					throw new InvalidOperationException("Prepared animal display controller was removed");
				}
				component.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("ACRID_E8_DISPLAY_FAILED " + ex));
			}
		}

		private void OnDestroy()
		{
			ReleaseUncommitted();
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
			registration?.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
}