Decompiled source of MUL T Skin Pack v0.2.0

BepInEx/plugins/EclipsePlaytestMULTDeepSalvageUnit/MULTDeepSalvageUnit.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTDeepSalvage;

[BepInPlugin("eclipseplaytest.mul-t.e3", "MUL-T - Deep-Salvage Unit (Playtest)", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTDeepSalvageUnit : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E3_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTDeepSalvageUnit owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTDeepSalvageUnit plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				((Renderer)target).localBounds = owner.powerMesh.bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e3";

	public const string Version = "0.1.0";

	private static MULTDeepSalvageUnit instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("deep-salvage-unit", "MUL-T - Deep-Salvage Unit (Playtest)", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)89, (byte)133, (byte)124, byte.MaxValue),
			new Color32((byte)24, (byte)37, (byte)42, byte.MaxValue),
			new Color32((byte)192, (byte)153, (byte)72, byte.MaxValue),
			new Color32((byte)174, (byte)190, (byte)181, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTDeepSalvageUnit));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e3");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E3_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E3"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTDeepSalvageUnit_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTDeepSalvageUnit_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E3";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E3_DEEP_SALVAGE_UNIT_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E3_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E3_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E3_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Unknown result type (might be due to invalid IL or missing references)
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_0395: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]))
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTDeepSalvageUnit",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTRefuseProcessor/MULTRefuseProcessor.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTRefuseProcessor;

[BepInPlugin("eclipseplaytest.mul-t.e5", "MUL-T - Refuse Processor", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTRefuseProcessor : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E5_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTRefuseProcessor owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTRefuseProcessor plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				Bounds bounds = owner.powerMesh.bounds;
				((Bounds)(ref bounds)).Expand(0.5f);
				((Renderer)target).localBounds = bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e5";

	public const string Version = "0.1.0";

	private static MULTRefuseProcessor instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("refuse-processor", "MUL-T - Refuse Processor", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)195, (byte)147, (byte)27, byte.MaxValue),
			new Color32((byte)62, (byte)78, (byte)43, byte.MaxValue),
			new Color32((byte)33, (byte)39, (byte)34, byte.MaxValue),
			new Color32((byte)232, (byte)178, (byte)35, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTRefuseProcessor));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e5");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E5_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E5"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTRefuseProcessor_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTRefuseProcessor_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E5";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E5_REFUSE_PROCESSOR_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E5_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E5_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E5_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: 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_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]) || float.IsNaN(array4[num5].x + array4[num5].y) || float.IsInfinity(array4[num5].x + array4[num5].y) || Math.Abs(((Vector3)(ref array3[num5])).sqrMagnitude - 1f) > 0.003f)
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTRefuseProcessor",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTSelfCheckout/MULTSelfCheckout.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTSelfCheckout;

[BepInPlugin("eclipseplaytest.mul-t.e7", "MUL-T - Self Checkout", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTSelfCheckout : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E7_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTSelfCheckout owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTSelfCheckout plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				Bounds bounds = owner.powerMesh.bounds;
				((Bounds)(ref bounds)).Expand(0.5f);
				((Renderer)target).localBounds = bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e7";

	public const string Version = "0.1.0";

	private static MULTSelfCheckout instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("self-checkout", "MUL-T - Self Checkout", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)210, (byte)214, (byte)204, byte.MaxValue),
			new Color32((byte)174, (byte)57, (byte)40, byte.MaxValue),
			new Color32((byte)153, (byte)112, (byte)65, byte.MaxValue),
			new Color32((byte)62, (byte)190, (byte)129, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTSelfCheckout));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e7");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E7_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E7"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTSelfCheckout_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTSelfCheckout_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E7";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E7_SELF_CHECKOUT_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E7_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E7_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E7_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: 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_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]) || float.IsNaN(array4[num5].x + array4[num5].y) || float.IsInfinity(array4[num5].x + array4[num5].y) || Math.Abs(((Vector3)(ref array3[num5])).sqrMagnitude - 1f) > 0.003f)
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTSelfCheckout",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTSoftServe/MULTSoftServe.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTSoftServe;

[BepInPlugin("eclipseplaytest.mul-t.e6", "MUL-T - Soft Serve", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTSoftServe : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E6_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTSoftServe owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTSoftServe plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				Bounds bounds = owner.powerMesh.bounds;
				((Bounds)(ref bounds)).Expand(0.5f);
				((Renderer)target).localBounds = bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e6";

	public const string Version = "0.1.0";

	private static MULTSoftServe instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("soft-serve", "MUL-T - Soft Serve", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)224, (byte)219, (byte)197, byte.MaxValue),
			new Color32((byte)100, (byte)171, (byte)193, byte.MaxValue),
			new Color32((byte)224, (byte)130, (byte)164, byte.MaxValue),
			new Color32((byte)191, (byte)146, (byte)79, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTSoftServe));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e6");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E6_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E6"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTSoftServe_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTSoftServe_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E6";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E6_SOFT_SERVE_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E6_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E6_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E6_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: 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_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]) || float.IsNaN(array4[num5].x + array4[num5].y) || float.IsInfinity(array4[num5].x + array4[num5].y) || Math.Abs(((Vector3)(ref array3[num5])).sqrMagnitude - 1f) > 0.003f)
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTSoftServe",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTStreetSweeper/MULTStreetSweeper.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTStreetSweeper;

[BepInPlugin("eclipseplaytest.mul-t.e4", "MUL-T - Street Sweeper", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTStreetSweeper : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E4_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTStreetSweeper owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTStreetSweeper plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				Bounds bounds = owner.powerMesh.bounds;
				((Bounds)(ref bounds)).Expand(0.5f);
				((Renderer)target).localBounds = bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e4";

	public const string Version = "0.1.0";

	private static MULTStreetSweeper instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("street-sweeper", "MUL-T - Street Sweeper", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)205, (byte)204, (byte)184, byte.MaxValue),
			new Color32((byte)30, (byte)37, (byte)37, byte.MaxValue),
			new Color32((byte)235, (byte)89, (byte)12, byte.MaxValue),
			new Color32((byte)97, (byte)160, (byte)168, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTStreetSweeper));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e4");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E4_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E4"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTStreetSweeper_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTStreetSweeper_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E4";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E4_STREET_SWEEPER_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E4_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E4_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E4_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: 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_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]) || float.IsNaN(array4[num5].x + array4[num5].y) || float.IsInfinity(array4[num5].x + array4[num5].y) || Math.Abs(((Vector3)(ref array3[num5])).sqrMagnitude - 1f) > 0.003f)
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTStreetSweeper",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTTimberHauler/MULTTimberHauler.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTTimber;

[BepInPlugin("eclipseplaytest.mul-t.e2", "MUL-T - Timber Hauler (Playtest)", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTTimberHauler : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E2_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTTimberHauler owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTTimberHauler plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				((Renderer)target).localBounds = owner.powerMesh.bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e2";

	public const string Version = "0.1.0";

	private static MULTTimberHauler instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("timber-hauler", "MUL-T - Timber Hauler (Playtest)", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)80, (byte)99, (byte)47, byte.MaxValue),
			new Color32((byte)28, (byte)36, (byte)27, byte.MaxValue),
			new Color32((byte)204, (byte)88, (byte)29, byte.MaxValue),
			new Color32((byte)210, (byte)151, (byte)55, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTTimberHauler));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e2");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E2_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E2"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTTimberHauler_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTTimberHauler_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E2";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E2_TIMBER_HAULER_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E2_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E2_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E2_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Unknown result type (might be due to invalid IL or missing references)
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_0395: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]))
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTTimberHauler",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTTotalAnnihilation/MULTTotalAnnihilation.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.Text;
using BepInEx;
using EntityStates;
using EntityStates.Toolbot;
using HG.Reflection;
using HarmonyLib;
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 EclipsePlaytestMULTTotalAnnihilation;

[BepInPlugin("eclipseplaytest.mul-t.e8", "MUL-T - Total Annihilation", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTTotalAnnihilation : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	[HarmonyPatch(typeof(ToolbotDualWield), "OnEnter")]
	private static class PowerModePatch
	{
		private static readonly FieldInfo Left = AccessTools.Field(typeof(ToolbotDualWield), "coverLeftInstance");

		private static readonly FieldInfo Right = AccessTools.Field(typeof(ToolbotDualWield), "coverRightInstance");

		private static readonly FieldInfo Prefab = AccessTools.Field(typeof(ToolbotDualWield), "coverPrefab");

		private static void Postfix(ToolbotDualWield __instance)
		{
			if (!Object.op_Implicit((Object)(object)instance) || !instance.registered)
			{
				return;
			}
			try
			{
				CharacterBody component = ((Component)((EntityState)__instance).outer).gameObject.GetComponent<CharacterBody>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelLocator) || !Object.op_Implicit((Object)(object)component.modelLocator.modelTransform))
				{
					return;
				}
				SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)component.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")));
				object? value = Prefab.GetValue(null);
				GameObject val2 = (GameObject)((value is GameObject) ? value : null);
				SkinnedMeshRenderer val3 = (Object.op_Implicit((Object)(object)val2) ? ((IEnumerable<SkinnedMeshRenderer>)val2.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2)) : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
				{
					throw new InvalidOperationException("Power Mode native renderer unavailable.");
				}
				FieldInfo[] array = new FieldInfo[2] { Left, Right };
				for (int num = 0; num < array.Length; num++)
				{
					object? value2 = array[num].GetValue(__instance);
					GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
					if (Object.op_Implicit((Object)(object)val4))
					{
						SkinnedMeshRenderer val5 = ((IEnumerable<SkinnedMeshRenderer>)val4.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => r.bones.Length == 2));
						if (!Object.op_Implicit((Object)(object)val5))
						{
							throw new InvalidOperationException("Power Mode cover renderer missing.");
						}
						if (!Object.op_Implicit((Object)(object)instance.powerMesh))
						{
							instance.powerMesh = instance.ReadMesh(Path.Combine(instance.folder, "power.meshbin"), val5, val3.sharedMesh);
						}
						val4.AddComponent<PowerCoverAppearance>().Initialize(instance, val, val5, val3);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSEPLAYTEST_MULT_E8_POWER_APPLY_FAILED: " + ex));
			}
		}
	}

	public sealed class PowerCoverAppearance : MonoBehaviour
	{
		private MULTTotalAnnihilation owner;

		private SkinnedMeshRenderer main;

		private SkinnedMeshRenderer target;

		private Mesh nativeMesh;

		private Material[] nativeMaterials;

		private Bounds nativeBounds;

		private Mesh lastMainMesh;

		private bool initialized;

		public void Initialize(MULTTotalAnnihilation plugin, SkinnedMeshRenderer body, SkinnedMeshRenderer cover, SkinnedMeshRenderer reference)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			owner = plugin;
			main = body;
			target = cover;
			nativeMesh = reference.sharedMesh;
			nativeMaterials = (Material[])((Renderer)reference).sharedMaterials.Clone();
			nativeBounds = ((Renderer)reference).localBounds;
			initialized = true;
			ApplyForCurrentSkin();
		}

		private void LateUpdate()
		{
			if (initialized && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)main) && Object.op_Implicit((Object)(object)target) && (Object)(object)lastMainMesh != (Object)(object)main.sharedMesh)
			{
				ApplyForCurrentSkin();
			}
		}

		private void ApplyForCurrentSkin()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			lastMainMesh = main.sharedMesh;
			if ((Object)(object)lastMainMesh == (Object)(object)owner.mesh)
			{
				target.sharedMesh = owner.powerMesh;
				((Renderer)target).sharedMaterials = (Material[])(object)new Material[1] { owner.material };
				Bounds bounds = owner.powerMesh.bounds;
				((Bounds)(ref bounds)).Expand(0.5f);
				((Renderer)target).localBounds = bounds;
			}
			else
			{
				RestoreIfOwned();
			}
		}

		public void RestoreIfOwned()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)owner) && (Object)(object)target.sharedMesh == (Object)(object)owner.powerMesh)
			{
				target.sharedMesh = nativeMesh;
				((Renderer)target).sharedMaterials = nativeMaterials;
				((Renderer)target).localBounds = nativeBounds;
			}
		}

		private void OnDestroy()
		{
			RestoreIfOwned();
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e8";

	public const string Version = "0.1.0";

	private static MULTTotalAnnihilation instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private Mesh powerMesh;

	private Harmony powerHooks;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("total-annihilation", "MUL-T - Total Annihilation", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)38, (byte)44, (byte)40, byte.MaxValue),
			new Color32((byte)100, (byte)107, (byte)98, byte.MaxValue),
			new Color32((byte)243, (byte)113, (byte)10, byte.MaxValue),
			new Color32((byte)16, (byte)21, (byte)19, byte.MaxValue)
		})
	};

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		instance = this;
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(MULTTotalAnnihilation));
		powerHooks = new Harmony("eclipseplaytest.mul-t.e8");
		powerHooks.PatchAll(typeof(PowerModePatch));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised += SyncDisplaySkins;
	}

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E8_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E8"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTTotalAnnihilation_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTTotalAnnihilation_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E8";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E8_TOTAL_ANNIHILATION_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E8_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E8_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E8_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: 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_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Expected O, but got Unknown
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]) || float.IsNaN(array4[num5].x + array4[num5].y) || float.IsInfinity(array4[num5].x + array4[num5].y) || Math.Abs(((Vector3)(ref array3[num5])).sqrMagnitude - 1f) > 0.003f)
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "MULTTotalAnnihilation",
			indexFormat = (IndexFormat)(num > 65535),
			vertices = array2,
			normals = array3,
			uv = array4,
			boneWeights = array5,
			bindposes = reference.bindposes,
			triangles = array8
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}

	private void OnDestroy()
	{
		if (powerHooks != null)
		{
			powerHooks.UnpatchSelf();
		}
		PowerCoverAppearance[] array = Object.FindObjectsOfType<PowerCoverAppearance>();
		foreach (PowerCoverAppearance obj in array)
		{
			obj.RestoreIfOwned();
			Object.Destroy((Object)(object)obj);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins));
		MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}

BepInEx/plugins/EclipsePlaytestMULTYardSalvager/MULTYardSalvager.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.Text;
using BepInEx;
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 EclipsePlaytestMULT;

[BepInPlugin("eclipseplaytest.mul-t.e1", "MUL-T - Yard Salvager (Playtest)", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class MULTYardSalvager : BaseUnityPlugin
{
	private sealed class Design
	{
		public string Slug;

		public string Name;

		public Color32[] Colors;

		public Design(string slug, string name, Color32[] colors)
		{
			Slug = slug;
			Name = name;
			Colors = colors;
		}
	}

	public const string Guid = "eclipseplaytest.mul-t.e1";

	public const string Version = "0.1.0";

	private static MULTYardSalvager instance;

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

	private float registrationDeadline;

	private string folder;

	private SkinDef skin;

	private Mesh mesh;

	private Material material;

	private GameObject modelPrefab;

	private int rendererIndex;

	private bool registered;

	private static readonly Design[] Designs = new Design[1]
	{
		new Design("yard-salvager", "MUL-T - Yard Salvager (Playtest)", (Color32[])(object)new Color32[4]
		{
			new Color32((byte)189, (byte)126, (byte)35, byte.MaxValue),
			new Color32((byte)33, (byte)40, (byte)40, byte.MaxValue),
			new Color32((byte)125, (byte)42, (byte)25, byte.MaxValue),
			new Color32((byte)228, (byte)209, (byte)155, byte.MaxValue)
		})
	};

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

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

	private IEnumerator RegisterAsync()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSEPLAYTEST_MULT_E1_REGISTRATION_BEGIN async loader 0.1.0");
		GameObject val = BodyCatalog.FindBodyPrefab("ToolbotBody");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("ToolbotBody is missing.");
		}
		modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>();
		if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytest_MULT_E1"))
		{
			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> load = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(load));
			while (!load.IsDone)
			{
				CheckLoadDeadline("skin parameters");
				yield return null;
			}
			baseParams = load.Result;
		}
		if (!Object.op_Implicit((Object)(object)baseParams))
		{
			throw new InvalidOperationException("MUL-T's base skin parameters are unavailable.");
		}
		SkinnedMeshRenderer[] componentsInChildren = modelPrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		SkinnedMeshRenderer target = componentsInChildren.First((SkinnedMeshRenderer r) => r.bones.Length == 64 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head"));
		rendererIndex = Array.IndexOf(componentsInChildren, target);
		Mesh referenceMesh = target.sharedMesh;
		if (!Object.op_Implicit((Object)(object)referenceMesh))
		{
			MeshReplacement val2 = baseParams.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target);
			referenceMesh = val2.mesh;
			if (!Object.op_Implicit((Object)(object)referenceMesh))
			{
				AsyncOperationHandle<Mesh> load2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
				retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(load2));
				while (!load2.IsDone)
				{
					CheckLoadDeadline("reference mesh");
					yield return null;
				}
				referenceMesh = load2.Result;
			}
		}
		if (!Object.op_Implicit((Object)(object)referenceMesh) || referenceMesh.bindposes.Length != target.bones.Length)
		{
			throw new InvalidOperationException("The installed MUL-T bind pose does not match the renderer.");
		}
		RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target);
		Material source = originalInfo.defaultMaterial;
		if (!Object.op_Implicit((Object)(object)source) && originalInfo.defaultMaterialAddress != null)
		{
			AsyncOperationHandle<Material> load3 = Addressables.LoadAssetAsync<Material>(((AssetReference)originalInfo.defaultMaterialAddress).RuntimeKey);
			retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(load3));
			while (!load3.IsDone)
			{
				CheckLoadDeadline("material");
				yield return null;
			}
			source = load3.Result;
		}
		if (!Object.op_Implicit((Object)(object)source))
		{
			source = ((Renderer)target).sharedMaterial;
		}
		if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader))
		{
			throw new InvalidOperationException("MUL-T's game shader is unavailable.");
		}
		List<SkinDef> additions = new List<SkinDef>();
		Design[] designs = Designs;
		foreach (Design design in designs)
		{
			string path = folder;
			mesh = ReadMesh(Path.Combine(path, "model.meshbin"), target, referenceMesh);
			((Object)mesh).name = "MULTYardSalvager_" + design.Slug;
			material = new Material(source)
			{
				name = "matMULTYardSalvager_" + design.Slug
			};
			material.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false));
			material.SetTexture("_NormalTex", (Texture)(object)Texture2D.normalTexture);
			material.SetColor("_Color", Color.white);
			material.SetFloat("_NormalStrength", 0f);
			material.SetFloat("_Smoothness", 0.28f);
			material.SetFloat("_SpecularStrength", 0.5f);
			material.SetFloat("_SpecularExponent", 8f);
			material.SetFloat("_EmPower", 0.35f);
			material.SetColor("_EmColor", Color.white);
			material.SetTexture("_EmTex", (Texture)(object)ReadTexture("emission.png", linear: false));
			material.DisableKeyword("LIMBREMOVAL");
			material.SetFloat("_LimbRemovalOn", 0f);
			RendererInfo val3 = originalInfo;
			val3.defaultMaterial = material;
			val3.defaultMaterialAddress = new AssetReferenceT<Material>("");
			SkinDefParams val4 = ScriptableObject.CreateInstance<SkinDefParams>();
			val4.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val3 };
			val4.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)target,
					mesh = mesh,
					meshAddress = new AssetReferenceT<Mesh>("")
				}
			};
			skin = ScriptableObject.CreateInstance<SkinDef>();
			((Object)skin).name = "skinEclipsePlaytest_MULT_E1";
			skin.nameToken = "ECLIPSEPLAYTEST_MULT_E1_YARD_SALVAGER_NAME";
			LanguageAPI.Add(skin.nameToken, design.Name);
			skin.icon = CreateIcon(design.Colors);
			skin.unlockableDef = null;
			skin.rootObject = modelPrefab;
			skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			skin.skinDefParams = val4;
			additions.Add(skin);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E1_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true"));
			yield return null;
		}
		controller.skins = controller.skins.Concat(additions).ToArray();
		registered = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E1_REGISTERED count=" + additions.Count + " version=0.1.0"));
	}

	private static Sprite CreateIcon(Color32[] colors)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color32[] array = (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));
				array[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) : colors[num]);
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
	}

	private void CheckLoadDeadline(string asset)
	{
		if (Time.realtimeSinceStartup > registrationDeadline)
		{
			throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin.");
		}
	}

	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 == "ToolbotBody"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			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();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E1_DISPLAY_READY skins=" + val2.skins.Length));
			}
		}
	}

	private Texture2D ReadTexture(string name, 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_004b: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = name,
			anisoLevel = 4,
			filterMode = (FilterMode)2
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false))
		{
			throw new InvalidDataException("Cannot decode " + name);
		}
		return val;
	}

	private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference)
	{
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_0365: Expected O, but got Unknown
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
		if (new string(binaryReader.ReadChars(4)) != "MTE1")
		{
			throw new InvalidDataException("Invalid mesh signature.");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != 64)
		{
			throw new InvalidDataException("Invalid mesh dimensions.");
		}
		int[] array = new int[num3];
		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));
			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());
			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.");
			}
			if (!Finite(array2[num5]) || !Finite(array3[num5]))
			{
				throw new InvalidDataException("Non-finite vertex.");
			}
			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 = "CommandoMULTYardSalvager",
			indexFormat = (IndexFormat)(num > 65535)
		};
		val2.vertices = array2;
		val2.normals = array3;
		val2.uv = array4;
		val2.boneWeights = array5;
		val2.bindposes = reference.bindposes;
		val2.triangles = array8;
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return AddNativeAlternateTools(val2, reference, renderer);
	}

	private Mesh AddNativeAlternateTools(Mesh authored, Mesh reference, SkinnedMeshRenderer renderer)
	{
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		HashSet<int> hashSet = new HashSet<int>();
		for (int i = 0; i < renderer.bones.Length; i++)
		{
			string text = (Object.op_Implicit((Object)(object)renderer.bones[i]) ? ((Object)renderer.bones[i]).name : "");
			if (text.StartsWith("spear", StringComparison.Ordinal) || text.StartsWith("saw", StringComparison.Ordinal) || text.StartsWith("grenade", StringComparison.Ordinal))
			{
				hashSet.Add(i);
			}
		}
		if (hashSet.Count == 0 || !reference.isReadable)
		{
			throw new InvalidDataException("Native alternate-tool geometry unavailable; registration aborted safely.");
		}
		Vector3[] vertices = reference.vertices;
		Vector3[] normals = reference.normals;
		BoneWeight[] boneWeights = reference.boneWeights;
		int[] triangles = reference.triangles;
		if (vertices.Length != boneWeights.Length || normals.Length != vertices.Length)
		{
			throw new InvalidDataException("Native tool mesh arrays differ.");
		}
		List<Vector3> list = new List<Vector3>(authored.vertices);
		List<Vector3> list2 = new List<Vector3>(authored.normals);
		List<Vector2> list3 = new List<Vector2>(authored.uv);
		List<BoneWeight> list4 = new List<BoneWeight>(authored.boneWeights);
		List<int> list5 = new List<int>(authored.triangles);
		Dictionary<int, int> dictionary = new Dictionary<int, int>();
		int num = 0;
		for (int j = 0; j < triangles.Length; j += 3)
		{
			if (!ToolVertex(boneWeights[triangles[j]], hashSet) || !ToolVertex(boneWeights[triangles[j + 1]], hashSet) || !ToolVertex(boneWeights[triangles[j + 2]], hashSet))
			{
				continue;
			}
			for (int k = 0; k < 3; k++)
			{
				int num2 = triangles[j + k];
				if (!dictionary.TryGetValue(num2, out var value))
				{
					value = list.Count;
					dictionary.Add(num2, value);
					list.Add(vertices[num2]);
					list2.Add(normals[num2]);
					list4.Add(boneWeights[num2]);
					list3.Add(new Vector2(0.875f, 0.25f));
				}
				list5.Add(value);
			}
			num++;
		}
		if (num == 0)
		{
			throw new InvalidDataException("No native alternate-tool triangles found.");
		}
		authored.Clear();
		authored.indexFormat = (IndexFormat)(list.Count > 65535);
		authored.SetVertices(list);
		authored.SetNormals(list2);
		authored.SetUVs(0, list3);
		authored.boneWeights = list4.ToArray();
		authored.bindposes = reference.bindposes;
		authored.SetTriangles(list5, 0);
		authored.RecalculateBounds();
		authored.RecalculateTangents();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSEPLAYTEST_MULT_E1_NATIVE_ALTERNATES triangles=" + num + "; draft steel palette; runtime motion untested"));
		return authored;
	}

	private static bool ToolVertex(BoneWeight w, HashSet<int> ids)
	{
		if ((((BoneWeight)(ref w)).weight0 <= 0f || ids.Contains(((BoneWeight)(ref w)).boneIndex0)) && (((BoneWeight)(ref w)).weight1 <= 0f || ids.Contains(((BoneWeight)(ref w)).boneIndex1)) && (((BoneWeight)(ref w)).weight2 <= 0f || ids.Contains(((BoneWeight)(ref w)).boneIndex2)))
		{
			if (!(((BoneWeight)(ref w)).weight3 <= 0f))
			{
				return ids.Contains(((BoneWeight)(ref w)).boneIndex3);
			}
			return true;
		}
		return false;
	}

	private static bool Finite(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(v.x + v.y + v.z))
		{
			return !float.IsInfinity(v.x + v.y + v.z);
		}
		return false;
	}
}