Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MUL T Skin Pack v0.2.0
BepInEx/plugins/EclipsePlaytestMULTDeepSalvageUnit/MULTDeepSalvageUnit.dll
Decompiled a week agousing 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 agousing 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 agousing 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 agousing 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 agousing 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 agousing 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 agousing 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 agousing 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; } }