Decompiled source of Void Fiend Skin Pack v0.1.0

BepInEx/plugins/VoidFiendBurntOffering/Eclipse.VoidFiend.E5.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE5
{
	[BepInPlugin("eclipseplaytest.void-fiend.e5", "Void Fiend - Burnt Offering (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendBurntOffering : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e5";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE5";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendBurntOffering instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E5_NAME", "Void Fiend - Burnt Offering (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendBurntOffering));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E5_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Burnt Offering skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Burnt Offering asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Burnt Offering 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("Burnt Offering asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE5" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Burnt Offering asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E5_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE5"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE5"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE5";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE5";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E5_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<BurntOfferingFormSwitch>()))
			{
				modelPrefab.AddComponent<BurntOfferingFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E5_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<BurntOfferingFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<BurntOfferingFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<BurntOfferingFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<BurntOfferingFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E5_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE5" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class BurntOfferingFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendBurntOffering.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendBurntOffering.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendBurntOffering.corruptedMesh)
				{
					target.sharedMesh = VoidFiendBurntOffering.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendBurntOffering.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendBurntOffering.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendBurntOffering.corruptedMesh : VoidFiendBurntOffering.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendContainmentImpossible/Eclipse.VoidFiend.E8.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE8
{
	[BepInPlugin("eclipseplaytest.void-fiend.e8", "Void Fiend - Containment Impossible (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendContainmentImpossible : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e8";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE8";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendContainmentImpossible instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E8_NAME", "Void Fiend - Containment Impossible (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendContainmentImpossible));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E8_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Containment Impossible skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Containment Impossible asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Containment Impossible 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("Containment Impossible asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE8" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Containment Impossible asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E8_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE8"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE8"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE8";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE8";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E8_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<ContainmentImpossibleFormSwitch>()))
			{
				modelPrefab.AddComponent<ContainmentImpossibleFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E8_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<ContainmentImpossibleFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<ContainmentImpossibleFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<ContainmentImpossibleFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<ContainmentImpossibleFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E8_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE8" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class ContainmentImpossibleFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendContainmentImpossible.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendContainmentImpossible.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendContainmentImpossible.corruptedMesh)
				{
					target.sharedMesh = VoidFiendContainmentImpossible.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendContainmentImpossible.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendContainmentImpossible.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendContainmentImpossible.corruptedMesh : VoidFiendContainmentImpossible.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendDesertCastaway/Eclipse.VoidFiend.E1.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE1
{
	[BepInPlugin("eclipseplaytest.void-fiend.e1", "Void Fiend - Desert Castaway (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendDesertCastaway : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e1";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE1";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendDesertCastaway instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E1_NAME", "Void Fiend - Desert Castaway (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendDesertCastaway));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E1_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Desert Castaway skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Desert Castaway asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Desert Castaway 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("Desert Castaway asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE1" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Desert Castaway asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E1_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE1"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE1"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE1";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE1";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E1_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<DesertCastawayFormSwitch>()))
			{
				modelPrefab.AddComponent<DesertCastawayFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E1_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<DesertCastawayFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<DesertCastawayFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<DesertCastawayFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<DesertCastawayFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E1_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE1" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class DesertCastawayFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendDesertCastaway.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendDesertCastaway.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendDesertCastaway.corruptedMesh)
				{
					target.sharedMesh = VoidFiendDesertCastaway.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendDesertCastaway.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendDesertCastaway.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendDesertCastaway.corruptedMesh : VoidFiendDesertCastaway.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendLiveWire/Eclipse.VoidFiend.E2.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE2
{
	[BepInPlugin("eclipseplaytest.void-fiend.e2", "Void Fiend - Live Wire (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendLiveWire : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e2";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE2";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendLiveWire instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E2_NAME", "Void Fiend - Live Wire (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendLiveWire));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E2_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Live Wire skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Live Wire asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Live Wire 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("Live Wire asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE2" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Live Wire asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E2_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE2"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE2"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE2";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE2";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E2_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<LiveWireFormSwitch>()))
			{
				modelPrefab.AddComponent<LiveWireFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E2_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<LiveWireFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<LiveWireFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<LiveWireFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<LiveWireFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E2_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE2" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class LiveWireFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendLiveWire.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendLiveWire.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendLiveWire.corruptedMesh)
				{
					target.sharedMesh = VoidFiendLiveWire.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendLiveWire.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendLiveWire.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendLiveWire.corruptedMesh : VoidFiendLiveWire.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendOrangeYouGlad/Eclipse.VoidFiend.E4.OrangeYouGlad.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 EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE4
{
	[BepInPlugin("eclipseplaytest.void-fiend.e4", "Void Fiend - Orange You Glad (Playtest)", "0.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendOrange : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e4";

		public const string Version = "0.1.3";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE4";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendOrange instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E4_NAME", "Void Fiend - Orange You Glad (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendOrange));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E4_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the orange skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid orange asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Orange 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("Orange asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "orange-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE4" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid orange asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E4_REGISTRATION_BEGIN version=0.1.3 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE4"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE4"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE4";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE4";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E4_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<OrangeFormSwitch>()))
			{
				modelPrefab.AddComponent<OrangeFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E4_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<OrangeFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<OrangeFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<OrangeFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<OrangeFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E4_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Expected O, but got Unknown
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE4" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class OrangeFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsOrange()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendOrange.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendOrange.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendOrange.corruptedMesh)
				{
					target.sharedMesh = VoidFiendOrange.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsOrange())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendOrange.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendOrange.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendOrange.corruptedMesh : VoidFiendOrange.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendPressureGuest/Eclipse.VoidFiend.E3.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE3
{
	[BepInPlugin("eclipseplaytest.void-fiend.e3", "Void Fiend - Pressure Guest (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendPressureGuest : 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 string materialMode;

			public AssetFile calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e3";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE3";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendPressureGuest instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E3_NAME", "Void Fiend - Pressure Guest (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendPressureGuest));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E3_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Pressure Guest skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Pressure Guest asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Pressure Guest 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("Pressure Guest asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE3" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Pressure Guest asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E3_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE3"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			if (manifest.materialMode != "native-dither-translucency")
			{
				throw new InvalidDataException("Pressure Guest requires its coverage atlas");
			}
			AsyncOperationHandle<Shader> transparentOp = Addressables.LoadAssetAsync<Shader>((object)"RoR2/Base/Shaders/HGStandardTransparent.shader");
			retainedAssets.Add(AsyncOperationHandle<Shader>.op_Implicit(transparentOp));
			while (!transparentOp.IsDone)
			{
				CheckDeadline("translucent mantle shader");
				yield return null;
			}
			if (!Object.op_Implicit((Object)(object)transparentOp.Result))
			{
				throw new InvalidOperationException("Native translucent shader unavailable");
			}
			Material val4 = new Material(transparentOp.Result)
			{
				name = "matEclipsePlaytestVoidFiendE3"
			};
			if (!val4.HasProperty("_useDither") || !val4.HasProperty("_ForceSpecOn"))
			{
				throw new InvalidOperationException("Unsupported native translucent shader");
			}
			val4.EnableKeyword("USE_DITHER");
			val4.SetFloat("_useDither", 1f);
			val4.DisableKeyword("USE_BLUE");
			val4.SetFloat("_useBlue", 0f);
			val4.EnableKeyword("FORCE_SPEC");
			val4.SetFloat("_ForceSpecOn", 1f);
			val4.SetFloat("_AlphaContrast", 1f);
			val4.SetFloat("_AlphaMidPoint", 0.5f);
			val4.SetFloat("_RampInfo", 4f);
			val4.SetFloat("_Cull", 2f);
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE3";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE3";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E3_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<PressureGuestFormSwitch>()))
			{
				modelPrefab.AddComponent<PressureGuestFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E3_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<PressureGuestFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<PressureGuestFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<PressureGuestFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<PressureGuestFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E3_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE3" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class PressureGuestFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendPressureGuest.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendPressureGuest.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendPressureGuest.corruptedMesh)
				{
					target.sharedMesh = VoidFiendPressureGuest.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendPressureGuest.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendPressureGuest.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendPressureGuest.corruptedMesh : VoidFiendPressureGuest.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendPublicInformation/Eclipse.VoidFiend.E6.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE6
{
	[BepInPlugin("eclipseplaytest.void-fiend.e6", "Void Fiend - Public Information (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendPublicInformation : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e6";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE6";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendPublicInformation instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E6_NAME", "Void Fiend - Public Information (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendPublicInformation));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E6_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Public Information skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Public Information asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Public Information 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("Public Information asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE6" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Public Information asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E6_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE6"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE6"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE6";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE6";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E6_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<PublicInformationFormSwitch>()))
			{
				modelPrefab.AddComponent<PublicInformationFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E6_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<PublicInformationFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<PublicInformationFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<PublicInformationFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<PublicInformationFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E6_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE6" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class PublicInformationFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendPublicInformation.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendPublicInformation.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendPublicInformation.corruptedMesh)
				{
					target.sharedMesh = VoidFiendPublicInformation.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendPublicInformation.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendPublicInformation.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendPublicInformation.corruptedMesh : VoidFiendPublicInformation.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}

BepInEx/plugins/VoidFiendSurpriseInside/Eclipse.VoidFiend.E7.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EclipseSkinRuntimeFix;
using HG.Reflection;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
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);
		}
	}
}
namespace EclipsePlaytestVoidFiendE7
{
	[BepInPlugin("eclipseplaytest.void-fiend.e7", "Void Fiend - Surprise Inside (Playtest)", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VoidFiendSurpriseInside : 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 calm;

			public AssetFile corrupted;

			public AssetFile albedo;

			public AssetFile emission;

			public AssetFile icon;
		}

		public const string Guid = "eclipseplaytest.void-fiend.e7";

		public const string Version = "0.1.2";

		public const string SkinId = "skinEclipsePlaytestVoidFiendE7";

		private const string BodyName = "VoidSurvivorBody";

		private const string Target = "mdlVoidSurvivorBody";

		private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" };

		private static VoidFiendSurpriseInside instance;

		internal static Mesh calmMesh;

		internal static Mesh corruptedMesh;

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

		private AssetManifest manifest;

		private GameObject modelPrefab;

		private SkinDef skin;

		private string folder;

		private float deadline;

		private bool registered;

		internal static SkinDef ActiveSkin
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.skin;
			}
		}

		private static bool registered_
		{
			get
			{
				if (Object.op_Implicit((Object)(object)instance))
				{
					return instance.registered;
				}
				return false;
			}
		}

		private void Awake()
		{
			instance = this;
			folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E7_NAME", "Void Fiend - Surprise Inside (Playtest)");
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendSurpriseInside));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
			MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
			CharacterBody.onBodyStartGlobal += AttachFormSwitch;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static IEnumerator InitializeSkin()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				yield break;
			}
			instance.deadline = Time.realtimeSinceStartup + 45f;
			IEnumerator routine = instance.Register();
			while (true)
			{
				bool flag;
				try
				{
					flag = routine.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E7_REGISTRATION_FAILED " + ex));
					break;
				}
				if (!flag)
				{
					break;
				}
				yield return null;
			}
			(routine as IDisposable)?.Dispose();
		}

		private void CheckDeadline(string what)
		{
			if (Time.realtimeSinceStartup > deadline)
			{
				throw new TimeoutException("Stopped loading " + what + "; startup continues without the Surprise Inside skin.");
			}
		}

		private byte[] ReadAsset(AssetFile entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64)
			{
				throw new InvalidDataException("Invalid Surprise Inside asset entry");
			}
			string text = Path.Combine(folder, entry.file);
			if (new FileInfo(text).Length > 67108864)
			{
				throw new InvalidDataException("Surprise Inside 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("Surprise Inside asset hash mismatch: " + entry.file);
			}
			return array;
		}

		private IEnumerator Register()
		{
			manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json")));
			if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE7" || string.IsNullOrWhiteSpace(manifest.revision))
			{
				throw new InvalidDataException("Invalid Surprise Inside asset identity");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E7_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision));
			GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>()))
			{
				throw new InvalidOperationException("VoidSurvivorBody missing");
			}
			modelPrefab = ((Component)val.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("Void Fiend base skin missing");
			}
			if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE7"))
			{
				yield break;
			}
			SkinDef baseSkin = controller.skins[0];
			SkinDefParams baseParams = baseSkin.skinDefParams;
			if (!Object.op_Implicit((Object)(object)baseParams) && 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("base parameters");
					yield return null;
				}
				baseParams = op.Result;
			}
			if (!Object.op_Implicit((Object)(object)baseParams))
			{
				throw new InvalidOperationException("Void Fiend base parameters unavailable");
			}
			Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams);
			SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody");
			if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71)
			{
				throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length);
			}
			Mesh reference = target.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target));
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2));
					while (!op2.IsDone)
					{
						CheckDeadline("native bind mesh");
						yield return null;
					}
					reference = op2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71)
			{
				throw new InvalidOperationException("Native bindposes unavailable or mismatched");
			}
			RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && 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("native material");
					yield return null;
				}
				val3 = op3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)target).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidOperationException("Native Void Fiend shader unavailable");
			}
			calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm");
			corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted");
			Material val4 = new Material(val3)
			{
				name = "matEclipsePlaytestVoidFiendE7"
			};
			val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false));
			val4.SetColor("_Color", Color.white);
			val4.DisableKeyword("FRESNEL_EMISSION");
			val4.SetFloat("_FEON", 0f);
			val4.SetTexture("_FresnelMask", (Texture)null);
			val4.SetTexture("_FresnelRamp", (Texture)null);
			val4.DisableKeyword("LIMBREMOVAL");
			val4.SetFloat("_LimbRemovalOn", 0f);
			val4.SetTexture("_NormalTex", (Texture)null);
			val4.SetFloat("_NormalStrength", 0f);
			val4.SetFloat("_Smoothness", 0.35f);
			val4.SetFloat("_SpecularStrength", 0.35f);
			val4.SetFloat("_SpecularExponent", 10f);
			val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false));
			val4.SetColor("_EmColor", Color.white);
			val4.SetFloat("_EmPower", 1.5f);
			RendererInfo val5 = info;
			val5.renderer = (Renderer)(object)target;
			val5.defaultMaterial = val4;
			val5.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val6).name = "paramsEclipsePlaytestVoidFiendE7";
			val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 };
			val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = calmMesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation
			{
				gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject,
				shouldActivate = false
			})).ToArray();
			val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val6.lightReplacements = Array.Empty<LightInfo>();
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytestVoidFiendE7";
			skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E7_NAME";
			skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon());
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val6;
			controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray();
			registered = true;
			if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<SurpriseInsideFormSwitch>()))
			{
				modelPrefab.AddComponent<SurpriseInsideFormSwitch>();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E7_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3));
		}

		private static void AttachFormSwitch(CharacterBody body)
		{
			if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0)
			{
				Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
				if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<SurpriseInsideFormSwitch>()))
				{
					((Component)val).gameObject.AddComponent<SurpriseInsideFormSwitch>();
				}
			}
		}

		private void SyncDisplaySkins()
		{
			if (!registered)
			{
				return;
			}
			SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody"));
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone();
				if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<SurpriseInsideFormSwitch>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<SurpriseInsideFormSwitch>();
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E7_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}

		private Texture2D ReadTexture(AssetFile entry, bool linear)
		{
			//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_0016: 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_0032: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = entry.file,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return val;
		}

		private Sprite ReadIcon(AssetFile entry)
		{
			//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_0017: Expected O, but got Unknown
			//IL_0056: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
			{
				name = entry.file
			};
			if (!ImageConversion.LoadImage(val, ReadAsset(entry), false))
			{
				throw new InvalidDataException("Cannot decode " + entry.file);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static Sprite CreateIcon()
		{
			//IL_0016: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4]
			{
				new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue),
				new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue),
				new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue),
				new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue)
			};
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color32[] array2 = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3));
					array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]);
				}
			}
			val.SetPixels32(array2);
			val.Apply(false, true);
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static bool Finite(float f)
		{
			if (!float.IsNaN(f))
			{
				return !float.IsInfinity(f);
			}
			return false;
		}

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

		internal static byte[] DecodeMeshPayload(byte[] data)
		{
			if (data == null)
			{
				throw new InvalidDataException("Missing mesh payload");
			}
			if (data.Length < 2 || data[0] != 31 || data[1] != 139)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data, writable: false);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[16384];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) != 0)
			{
				if (memoryStream.Length + num > 33554432)
				{
					throw new InvalidDataException("Decoded mesh exceeds limit");
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form)
		{
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			data = DecodeMeshPayload(data);
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false));
			if (new string(binaryReader.ReadChars(4)) != "PWE1")
			{
				throw new InvalidDataException("Invalid mesh signature.");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71)
			{
				throw new InvalidDataException("Invalid mesh dimensions.");
			}
			int[] array = new int[num3];
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < num3; i++)
			{
				int num4 = binaryReader.ReadInt32();
				if (num4 < 1 || num4 > 128)
				{
					throw new InvalidDataException("Invalid bone name.");
				}
				string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4));
				if (!hashSet.Add(name))
				{
					throw new InvalidDataException("Duplicate payload bone: " + name);
				}
				array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name);
				if (array[i] < 0)
				{
					throw new InvalidDataException("Missing reference bone: " + name);
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			Vector2[] array4 = (Vector2[])(object)new Vector2[num];
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int num5 = 0; num5 < num; num5++)
			{
				array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y))
				{
					throw new InvalidDataException("Nonfinite vertex");
				}
				int[] array6 = new int[4];
				for (int num6 = 0; num6 < 4; num6++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num3)
					{
						throw new InvalidDataException("Bone out of range.");
					}
					array6[num6] = array[num7];
				}
				float[] array7 = new float[4];
				for (int num8 = 0; num8 < 4; num8++)
				{
					array7[num8] = binaryReader.ReadSingle();
				}
				if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f)
				{
					throw new InvalidDataException("Invalid skin weight.");
				}
				int num9 = num5;
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array6[0];
				((BoneWeight)(ref val)).boneIndex1 = array6[1];
				((BoneWeight)(ref val)).boneIndex2 = array6[2];
				((BoneWeight)(ref val)).boneIndex3 = array6[3];
				((BoneWeight)(ref val)).weight0 = array7[0];
				((BoneWeight)(ref val)).weight1 = array7[1];
				((BoneWeight)(ref val)).weight2 = array7[2];
				((BoneWeight)(ref val)).weight3 = array7[3];
				array5[num9] = val;
			}
			int[] array8 = new int[num2];
			for (int num10 = 0; num10 < num2; num10++)
			{
				array8[num10] = binaryReader.ReadInt32();
				if (array8[num10] < 0 || array8[num10] >= num)
				{
					throw new InvalidDataException("Triangle out of range.");
				}
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			Mesh val2 = new Mesh
			{
				name = "meshEclipsePlaytestVoidFiendE7" + form,
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array2,
				normals = array3,
				uv = array4,
				boneWeights = array5,
				bindposes = reference.bindposes,
				triangles = array8
			};
			val2.RecalculateBounds();
			val2.RecalculateTangents();
			return val2;
		}
	}
	public sealed class SurpriseInsideFormSwitch : MonoBehaviour
	{
		private CharacterBody body;

		private ModelSkinController controller;

		private SkinnedMeshRenderer target;

		private bool subscribed;

		private bool acquired;

		private bool previousOffscreen;

		private Bounds previousBounds;

		private Bounds ownedBounds;

		private void OnEnable()
		{
			Subscribe();
		}

		private void Subscribe()
		{
			if (!subscribed)
			{
				controller = ((Component)this).GetComponent<ModelSkinController>();
				if (Object.op_Implicit((Object)(object)controller))
				{
					controller.onSkinApplied += Applied;
					subscribed = true;
				}
				body = ((Component)this).GetComponentInParent<CharacterBody>();
			}
		}

		private void Applied(int index)
		{
			Release();
		}

		private bool IsSelectedSkin()
		{
			if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendSurpriseInside.ActiveSkin))
			{
				return false;
			}
			int currentSkinIndex = controller.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length)
			{
				return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendSurpriseInside.ActiveSkin;
			}
			return false;
		}

		private void Release()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (acquired && Object.op_Implicit((Object)(object)target))
			{
				if (((Renderer)target).localBounds == ownedBounds)
				{
					((Renderer)target).localBounds = previousBounds;
				}
				if (target.updateWhenOffscreen)
				{
					target.updateWhenOffscreen = previousOffscreen;
				}
				if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendSurpriseInside.corruptedMesh)
				{
					target.sharedMesh = VoidFiendSurpriseInside.calmMesh;
				}
			}
			acquired = false;
		}

		private void LateUpdate()
		{
			//IL_00a5: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			Subscribe();
			if (!IsSelectedSkin())
			{
				Release();
				return;
			}
			if (!Object.op_Implicit((Object)(object)target))
			{
				target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"));
			}
			if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendSurpriseInside.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendSurpriseInside.corruptedMesh))
			{
				Release();
				return;
			}
			if (!acquired)
			{
				previousBounds = ((Renderer)target).localBounds;
				previousOffscreen = target.updateWhenOffscreen;
				ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f));
				((Renderer)target).localBounds = ownedBounds;
				target.updateWhenOffscreen = true;
				acquired = true;
			}
			Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendSurpriseInside.corruptedMesh : VoidFiendSurpriseInside.calmMesh);
			if ((Object)(object)target.sharedMesh != (Object)(object)val)
			{
				target.sharedMesh = val;
			}
		}

		private void OnDisable()
		{
			Release();
			if (subscribed && Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied -= Applied;
			}
			subscribed = false;
		}
	}
}