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 Rodanius Skin Runtime v0.1.1
BepInEx/plugins/RodaniusSkinRuntime/Eclipse.LoaderSkins.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using EntityStates; using HG.Reflection; using On.RoR2.Projectile; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using Rodanius.Standalone; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace Eclipse.LoaderSkins { internal sealed class LoaderBearClearance { private readonly Transform space; private readonly Transform head; private readonly Transform[] a = (Transform[])(object)new Transform[2]; private readonly Transform[] b = (Transform[])(object)new Transform[2]; private readonly Transform[] c = (Transform[])(object)new Transform[2]; private readonly Vector3[] paw = (Vector3[])(object)new Vector3[2]; private readonly Vector3 neck; private readonly Vector3 skull; private readonly CharacterBody body; public LoaderBearClearance(Transform model, Transform rendererSpace, Transform[] visual, LoaderRig rig) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) space = rendererSpace; body = ((Component)model).GetComponentInParent<CharacterBody>(); int num = Find(rig, "head"); head = visual[num]; neck = Local(rig, num, new Vector3(0f, 0.1f, 1.75f)); skull = Local(rig, num, new Vector3(0f, -0.035f, 2.4f)); for (int i = 0; i < 2; i++) { string text = ((i == 0) ? "l" : "r"); int num2 = Find(rig, "mech.upper_arm." + text); int num3 = Find(rig, "mech.lower_arm." + text); int num4 = Find(rig, "mech.hand." + text); a[i] = visual[num2]; b[i] = visual[num3]; c[i] = visual[num4]; Matrix4x4 val = Bind(rig, num4); Matrix4x4 inverse = ((Matrix4x4)(ref val)).inverse; Vector3 val2 = Vector4.op_Implicit(((Matrix4x4)(ref inverse)).GetColumn(3)); paw[i] = ((Matrix4x4)(ref val)).MultiplyPoint3x4(val2 + new Vector3((i == 0) ? (-0.08f) : 0.08f, -0.025f, -0.16f)); } } private static int Find(LoaderRig rig, string name) { for (int i = 0; i < rig.bones.Length; i++) { if (rig.bones[i].name == name) { return i; } } throw new InvalidOperationException("Missing bear bone " + name); } private static Matrix4x4 Bind(LoaderRig rig, int i) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 result = default(Matrix4x4); for (int j = 0; j < 16; j++) { ((Matrix4x4)(ref result))[j / 4, j % 4] = rig.bones[i].bindpose[j]; } return result; } private static Vector3 Local(LoaderRig rig, int i, Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 val = Bind(rig, i); return ((Matrix4x4)(ref val)).MultiplyPoint3x4(point); } public void Apply() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_033f: 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_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: 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_034d: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_037f: 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_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent) && !body.healthComponent.alive) { return; } Vector3 val = head.TransformPoint(neck); Vector3 val2 = head.TransformPoint(skull) - val; float num = 0.68f * Mathf.Max(new float[3] { Mathf.Abs(space.lossyScale.x), Mathf.Abs(space.lossyScale.y), Mathf.Abs(space.lossyScale.z) }); for (int i = 0; i < 2; i++) { Vector3 val3 = c[i].TransformPoint(paw[i]); Vector3 val4 = val + val2 * Mathf.Clamp01(Vector3.Dot(val3 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); Vector3 val5 = val3 - val4; float magnitude = ((Vector3)(ref val5)).magnitude; if (magnitude >= num) { continue; } float num2 = Mathf.SmoothStep(0f, 1f, (num - magnitude) / (0.2f * num / 0.68f)); Vector3 val6 = space.TransformDirection(new Vector3((i == 0) ? (-0.25f) : 0.25f, 0f, 0f)) * num2; Vector3 val7 = val5 + val6; Vector3 val8 = ((Vector3)(ref val7)).normalized; if (((Vector3)(ref val8)).sqrMagnitude < 0.5f) { val8 = space.TransformDirection((i == 0) ? Vector3.left : Vector3.right); } Vector3 val9 = c[i].position + (val4 + val8 * num - val3); val7 = b[i].position - a[i].position; float magnitude2 = ((Vector3)(ref val7)).magnitude; val7 = c[i].position - b[i].position; float num3 = magnitude2 + ((Vector3)(ref val7)).magnitude - 0.0005f; val7 = val9 - a[i].position; if (((Vector3)(ref val7)).magnitude > num3) { Vector3 val10 = a[i].position + val3 - c[i].position; Vector3 val11 = val + val2 * Mathf.Clamp01(Vector3.Dot(val10 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); val7 = val10 - val11; Vector3 val12 = ((Vector3)(ref val7)).normalized; if (((Vector3)(ref val12)).sqrMagnitude < 0.5f) { val12 = space.TransformDirection((i == 0) ? Vector3.left : Vector3.right); } Vector3 val13 = val11 + val12 * num; Vector3 val14 = val4 + val8 * num; float num4 = 0f; float num5 = 1f; for (int j = 0; j < 14; j++) { float num6 = (num4 + num5) * 0.5f; Vector3 val15 = Vector3.Lerp(val14, val13, num6); Vector3 val16 = val + val2 * Mathf.Clamp01(Vector3.Dot(val15 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); val7 = val15 - val16; val15 = val16 + ((Vector3)(ref val7)).normalized * num; val7 = val15 - val10; if (((Vector3)(ref val7)).magnitude <= num3 - 0.0001f) { num5 = num6; } else { num4 = num6; } } Vector3 val17 = Vector3.Lerp(val14, val13, num5); Vector3 val18 = val + val2 * Mathf.Clamp01(Vector3.Dot(val17 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); val7 = val17 - val18; val17 = val18 + ((Vector3)(ref val7)).normalized * num; val9 = c[i].position + val17 - val3; } Quaternion rotation = c[i].rotation; Solve(i, val9, rotation); } } private void Solve(int s, Vector3 target, Quaternion orientation) { //IL_0008: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) Vector3 position = a[s].position; Vector3 val = b[s].position - position; Vector3 val2 = c[s].position - b[s].position; Vector3 val3 = target - position; float magnitude = ((Vector3)(ref val)).magnitude; float magnitude2 = ((Vector3)(ref val2)).magnitude; float magnitude3 = ((Vector3)(ref val3)).magnitude; if (!(magnitude < 0.001f) && !(magnitude2 < 0.001f) && !(magnitude3 < 0.001f)) { float num = Mathf.Clamp(magnitude3, Mathf.Abs(magnitude - magnitude2) + 0.0005f, magnitude + magnitude2 - 0.0005f); Vector3 val4 = val3 / magnitude3; Vector3 val5 = Vector3.ProjectOnPlane(val, val4); if (((Vector3)(ref val5)).sqrMagnitude < 1E-05f) { val5 = Vector3.ProjectOnPlane(space.TransformDirection(new Vector3((s == 0) ? (-0.5f) : 0.5f, 0.4f, 0.1f)), val4); } Vector3 normalized = ((Vector3)(ref val5)).normalized; if (!(((Vector3)(ref normalized)).sqrMagnitude < 0.5f)) { float num2 = (magnitude * magnitude + num * num - magnitude2 * magnitude2) / (2f * num); float num3 = Mathf.Sqrt(Mathf.Max(0f, magnitude * magnitude - num2 * num2)); Vector3 val6 = position + val4 * num2 + normalized * num3; a[s].rotation = Quaternion.FromToRotation(val, val6 - position) * a[s].rotation; b[s].rotation = Quaternion.FromToRotation(c[s].position - b[s].position, position + val4 * num - b[s].position) * b[s].rotation; c[s].rotation = orientation; } } } } internal sealed class LoaderBowlingClearance { private readonly Transform space; private readonly Transform head; private readonly Transform[] centers = (Transform[])(object)new Transform[2]; private readonly Transform[] a = (Transform[])(object)new Transform[2]; private readonly Transform[] b = (Transform[])(object)new Transform[2]; private readonly Transform[] c = (Transform[])(object)new Transform[2]; private readonly Vector3[] paw = (Vector3[])(object)new Vector3[2]; private readonly Vector3 neck; private readonly Vector3 skull; private readonly CharacterBody body; public LoaderBowlingClearance(Transform model, Transform rendererSpace, Transform[] visual, LoaderRig rig) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) space = rendererSpace; body = ((Component)model).GetComponentInParent<CharacterBody>(); int num = Find(rig, "chest"); head = visual[num]; neck = Local(rig, num, new Vector3(0f, 0.065f, 1.33f)); skull = Local(rig, num, new Vector3(0f, 0.065f, 1.33f)); for (int i = 0; i < 2; i++) { string text = ((i == 0) ? "l" : "r"); int num2 = Find(rig, "mech.upper_arm." + text); int num3 = Find(rig, "mech.lower_arm." + text); int num4 = Find(rig, "mech.hand." + text); a[i] = visual[num2]; b[i] = visual[num3]; c[i] = visual[num4]; int num5 = Find(rig, "mech.hand.end." + text); centers[i] = visual[num5]; Matrix4x4 val = Bind(rig, num5); Matrix4x4 val2 = Bind(rig, num4); val2 = ((Matrix4x4)(ref val2)).inverse; Vector3 val3 = Vector4.op_Implicit(((Matrix4x4)(ref val2)).GetColumn(3)); paw[i] = ((Matrix4x4)(ref val)).MultiplyPoint3x4(val3 + new Vector3((i == 0) ? 0.07f : (-0.07f), -0.086f, 0.066f)); } } private static float MaxScale(Transform t) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 lossyScale = t.lossyScale; return Mathf.Max(new float[3] { Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z) }); } private static int Find(LoaderRig rig, string name) { for (int i = 0; i < rig.bones.Length; i++) { if (rig.bones[i].name == name) { return i; } } throw new InvalidOperationException("Missing bowling bone " + name); } private static Matrix4x4 Bind(LoaderRig rig, int i) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 result = default(Matrix4x4); for (int j = 0; j < 16; j++) { ((Matrix4x4)(ref result))[j / 4, j % 4] = rig.bones[i].bindpose[j]; } return result; } private static Vector3 Local(LoaderRig rig, int i, Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 val = Bind(rig, i); return ((Matrix4x4)(ref val)).MultiplyPoint3x4(point); } public void Apply() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0342: 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_034b: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_034f: 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_0352: 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_0374: 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_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: 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_03ee: 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_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent) && !body.healthComponent.alive) { return; } Vector3 val = head.TransformPoint(neck); Vector3 val2 = head.TransformPoint(skull) - val; float num = MaxScale(space); float num2 = 0.49f * MaxScale(head); for (int i = 0; i < 2; i++) { float num3 = MaxScale(centers[i]); if (num3 < 0.01f) { continue; } float num4 = num2 + 0.33f * num3 + 0.025f * num; Vector3 val3 = centers[i].TransformPoint(paw[i]); Vector3 val4 = val + val2 * Mathf.Clamp01(Vector3.Dot(val3 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); Vector3 val5 = val3 - val4; float magnitude = ((Vector3)(ref val5)).magnitude; if (magnitude >= num4) { continue; } float num5 = Mathf.SmoothStep(0f, 1f, (num4 - magnitude) / (0.2f * num)); Vector3 val6 = space.TransformDirection(new Vector3((i == 0) ? (-0.25f) : 0.25f, 0f, 0f)) * num5; Vector3 val7 = val5 + val6; Vector3 val8 = ((Vector3)(ref val7)).normalized; if (((Vector3)(ref val8)).sqrMagnitude < 0.5f) { val8 = space.TransformDirection((i == 0) ? Vector3.left : Vector3.right); } Vector3 val9 = c[i].position + (val4 + val8 * num4 - val3); val7 = b[i].position - a[i].position; float magnitude2 = ((Vector3)(ref val7)).magnitude; val7 = c[i].position - b[i].position; float num6 = magnitude2 + ((Vector3)(ref val7)).magnitude - 0.0005f; val7 = val9 - a[i].position; if (((Vector3)(ref val7)).magnitude > num6) { Vector3 val10 = a[i].position + val3 - c[i].position; Vector3 val11 = val + val2 * Mathf.Clamp01(Vector3.Dot(val10 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); val7 = val10 - val11; Vector3 val12 = ((Vector3)(ref val7)).normalized; if (((Vector3)(ref val12)).sqrMagnitude < 0.5f) { val12 = space.TransformDirection((i == 0) ? Vector3.left : Vector3.right); } Vector3 val13 = val11 + val12 * num4; Vector3 val14 = val4 + val8 * num4; float num7 = 0f; float num8 = 1f; for (int j = 0; j < 14; j++) { float num9 = (num7 + num8) * 0.5f; Vector3 val15 = Vector3.Lerp(val14, val13, num9); Vector3 val16 = val + val2 * Mathf.Clamp01(Vector3.Dot(val15 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); val7 = val15 - val16; val15 = val16 + ((Vector3)(ref val7)).normalized * num4; val7 = val15 - val10; if (((Vector3)(ref val7)).magnitude <= num6 - 0.0001f) { num8 = num9; } else { num7 = num9; } } Vector3 val17 = Vector3.Lerp(val14, val13, num8); Vector3 val18 = val + val2 * Mathf.Clamp01(Vector3.Dot(val17 - val, val2) / Mathf.Max(((Vector3)(ref val2)).sqrMagnitude, 1E-05f)); val7 = val17 - val18; val17 = val18 + ((Vector3)(ref val7)).normalized * num4; val9 = c[i].position + val17 - val3; } Quaternion rotation = c[i].rotation; Solve(i, val9, rotation); } } private void Solve(int s, Vector3 target, Quaternion orientation) { //IL_0008: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) Vector3 position = a[s].position; Vector3 val = b[s].position - position; Vector3 val2 = c[s].position - b[s].position; Vector3 val3 = target - position; float magnitude = ((Vector3)(ref val)).magnitude; float magnitude2 = ((Vector3)(ref val2)).magnitude; float magnitude3 = ((Vector3)(ref val3)).magnitude; if (!(magnitude < 0.001f) && !(magnitude2 < 0.001f) && !(magnitude3 < 0.001f)) { float num = Mathf.Clamp(magnitude3, Mathf.Abs(magnitude - magnitude2) + 0.0005f, magnitude + magnitude2 - 0.0005f); Vector3 val4 = val3 / magnitude3; Vector3 val5 = Vector3.ProjectOnPlane(val, val4); if (((Vector3)(ref val5)).sqrMagnitude < 1E-05f) { val5 = Vector3.ProjectOnPlane(space.TransformDirection(new Vector3((s == 0) ? (-0.5f) : 0.5f, 0.4f, 0.1f)), val4); } Vector3 normalized = ((Vector3)(ref val5)).normalized; if (!(((Vector3)(ref normalized)).sqrMagnitude < 0.5f)) { float num2 = (magnitude * magnitude + num * num - magnitude2 * magnitude2) / (2f * num); float num3 = Mathf.Sqrt(Mathf.Max(0f, magnitude * magnitude - num2 * num2)); Vector3 val6 = position + val4 * num2 + normalized * num3; a[s].rotation = Quaternion.FromToRotation(val, val6 - position) * a[s].rotation; b[s].rotation = Quaternion.FromToRotation(c[s].position - b[s].position, position + val4 * num - b[s].position) * b[s].rotation; c[s].rotation = orientation; } } } } [BepInPlugin("eclipseplaytest.loader.collection", "Eclipse Loader Skins (Private Playtest)", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class LoaderCollection : BaseUnityPlugin { [Serializable] public sealed class Manifest { public int schema; public Tier[] tiers; } [Serializable] public sealed class Tier { public int tier; public string name; public string folder; } public const string Guid = "eclipseplaytest.loader.collection"; public const string Version = "0.2.0"; public static readonly Dictionary<Mesh, LoaderDefinition> ByMesh = new Dictionary<Mesh, LoaderDefinition>(); public static readonly Dictionary<string, LoaderDefinition> BySkin = new Dictionary<string, LoaderDefinition>(); public static readonly Dictionary<int, string> ProjectileKinds = new Dictionary<int, string>(); private static LoaderCollection instance; private string folder; private float deadline; private GameObject model; private GameObject display; private bool registered; private readonly List<AsyncOperationHandle> handles = new List<AsyncOperationHandle>(); private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(LoaderCollection)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplay)); MainMenuController.OnMainMenuInitialised += SyncDisplay; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(SurvivorCatalog), typeof(ProjectileCatalog) })] private static IEnumerator Initialize() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 90f; IEnumerator e = instance.Register(); try { while (true) { bool flag; try { flag = e.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSE_LOADER_REGISTRATION_FAILED " + ex)); break; } if (flag) { yield return e.Current; continue; } break; } } finally { IDisposable disposable = e as IDisposable; if (disposable != null) { disposable.Dispose(); } } } private IEnumerator Load<T>(object key, Action<T> set) where T : Object { AsyncOperationHandle<T> op = Addressables.LoadAssetAsync<T>(key); handles.Add(AsyncOperationHandle<T>.op_Implicit(op)); while (!op.IsDone) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Loader asset loading exceeded deadline"); } yield return null; } if (!Object.op_Implicit((Object)(object)op.Result)) { throw new InvalidDataException("Missing Loader native asset " + key); } set(op.Result); } private IEnumerator Register() { List<SkinRecord> list = SkinDiscovery.Load("loader", delegate(string m) { ((BaseUnityPlugin)this).Logger.LogWarning((object)m); }); if (list.Count == 0) { yield break; } Manifest manifest = new Manifest { schema = 1, tiers = list.Select((SkinRecord r) => new Tier { tier = r.tier, name = r.name, folder = r.AssetRoot }).ToArray() }; GameObject val = BodyCatalog.FindBodyPrefab("LoaderBody"); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("LoaderBody missing"); } model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(val); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab)) { throw new InvalidOperationException("Loader display missing"); } display = ((Component)val2.displayPrefab.GetComponentInChildren<CharacterModel>(true)).gameObject; ModelSkinController ctrl = model.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)ctrl) || ctrl.skins.Length == 0) { throw new InvalidOperationException("Loader skins missing"); } SkinDef stock = ctrl.skins[0]; SkinDefParams bp = stock.skinDefParams; if (!Object.op_Implicit((Object)(object)bp)) { IEnumerator load = Load<SkinDefParams>(((AssetReference)stock.skinDefParamsAddress).RuntimeKey, (Action<SkinDefParams>)delegate(SkinDefParams v) { bp = v; }); while (load.MoveNext()) { yield return null; } } SkinnedMeshRenderer target = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, bp).Single((SkinnedMeshRenderer r) => ((Object)r).name == "PilotFemaleMesh"); RendererInfo val3 = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material native = val3.defaultMaterial; if (!Object.op_Implicit((Object)(object)native)) { IEnumerator load = Load<Material>(((AssetReference)val3.defaultMaterialAddress).RuntimeKey, (Action<Material>)delegate(Material v) { native = v; }); while (load.MoveNext()) { yield return null; } } if (!Object.op_Implicit((Object)(object)native) || !Object.op_Implicit((Object)(object)native.shader)) { throw new InvalidOperationException("Loader native material unavailable"); } List<SkinDef> next = new List<SkinDef>(ctrl.skins); List<LoaderDefinition> pending = new List<LoaderDefinition>(); HashSet<int> hashSet = new HashSet<int>(); Tier[] tiers = manifest.tiers; GameObject[] array; foreach (Tier tier in tiers) { try { if (tier.tier < 1 || tier.tier > 8 || !hashSet.Add(tier.tier) || Path.GetFileName(tier.folder) != "e" + tier.tier || string.IsNullOrEmpty(tier.name)) { throw new InvalidDataException("Loader tier identity"); } string path = Path.Combine(folder, tier.folder); LoaderRig loaderRig = JsonUtility.FromJson<LoaderRig>(File.ReadAllText(Path.Combine(path, "rig.json"))); ValidateRig(loaderRig, tier.tier); array = (GameObject[])(object)new GameObject[2] { model, display }; for (int num2 = 0; num2 < array.Length; num2++) { SkinnedMeshRenderer val4 = array[num2].GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null).Single((SkinnedMeshRenderer x) => ((Object)x).name == "PilotFemaleMesh"); for (int num3 = 0; num3 < 136; num3++) { if (val4.bones.Length != 136 || !Object.op_Implicit((Object)(object)val4.bones[num3]) || ((Object)val4.bones[num3]).name != loaderRig.bones[num3].name) { throw new InvalidOperationException("Loader ordered native bone mismatch " + num3); } } } LoaderDefinition loaderDefinition = new LoaderDefinition { Tier = tier.tier, Name = tier.name, Rig = loaderRig }; loaderDefinition.Body = ReadMesh(Path.Combine(path, "body.meshbin"), loaderRig); loaderDefinition.Hook = ReadMesh(Path.Combine(path, "hook.meshbin"), null); loaderDefinition.Yank = ReadMesh(Path.Combine(path, "yank.meshbin"), null); loaderDefinition.Pylon = ReadMesh(Path.Combine(path, "pylon.meshbin"), null); loaderDefinition.Material = new Material(native) { name = "matEclipseLoaderE" + tier.tier }; Material material = loaderDefinition.Material; material.SetTexture("_MainTex", (Texture)(object)Texture(Path.Combine(path, "albedo.png"))); material.SetColor("_Color", Color.white); material.SetFloat("_NormalStrength", 0f); material.SetFloat("_Smoothness", (tier.tier == 5) ? 0.65f : 0.12f); material.SetFloat("_SpecularStrength", (tier.tier == 5) ? 0.45f : 0.18f); material.SetFloat("_SpecularExponent", 8f); material.SetFloat("_EmPower", 0f); material.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture); material.DisableKeyword("FLOWMAP"); material.SetFloat("_FlowmapOn", 0f); material.SetFloat("_FlowEmissionStrength", 0f); material.DisableKeyword("LIMBREMOVAL"); material.SetFloat("_LimbRemovalOn", 0f); material.DisableKeyword("FORCE_SPEC"); material.SetFloat("_ForceSpecOn", 0f); Mesh val5 = new Mesh { name = "EclipseLoaderE" + tier.tier + "EmptyNativeCompanions" }; val5.vertices = Array.Empty<Vector3>(); val5.triangles = Array.Empty<int>(); RendererInfo[] array2 = (RendererInfo[])bp.rendererInfos.Clone(); for (int num4 = 0; num4 < array2.Length; num4++) { if ((Object)(object)array2[num4].renderer == (Object)(object)target) { array2[num4].defaultMaterial = material; array2[num4].defaultMaterialAddress = new AssetReferenceT<Material>(""); } } List<MeshReplacement> list2 = new List<MeshReplacement>(); SkinnedMeshRenderer[] skinRenderers = model.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, bp); foreach (SkinnedMeshRenderer val6 in skinRenderers) { if ((Object)(object)val6 == (Object)(object)target || ((Object)val6).name == "LoaderMechMesh" || ((Object)val6).name == "PilotFemaleFoldedOverJumpsuit") { list2.Add(new MeshReplacement { renderer = (Renderer)(object)val6, mesh = (((Object)(object)val6 == (Object)(object)target) ? loaderDefinition.Body : val5), meshAddress = new AssetReferenceT<Mesh>("") }); } } if (list2.Count != 3) { throw new InvalidOperationException("Unexpected Loader companion set"); } SkinDefParams val7 = ScriptableObject.CreateInstance<SkinDefParams>(); val7.rendererInfos = array2; val7.meshReplacements = list2.ToArray(); SkinDef skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = loaderRig.skinId; skin.nameToken = "ECLIPSE_LOADER_E" + tier.tier; LanguageAPI.Add(skin.nameToken, tier.name + " (Playtest)"); skin.rootObject = model; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { stock }; skin.skinDefParams = val7; skin.unlockableDef = null; Texture2D val8 = Texture(Path.Combine(path, "icon.png")); skin.icon = Sprite.Create(val8, new Rect(0f, 0f, (float)((Texture)val8).width, (float)((Texture)val8).height), new Vector2(0.5f, 0.5f)); loaderDefinition.Marker = new SkinDefMarker { Skin = skin }; if (next.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)skin).name)) { throw new InvalidOperationException("Duplicate Loader skin " + ((Object)skin).name); } pending.Add(loaderDefinition); next.Add(skin); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("RODANIUS_LOADER_SKIN_FAILED tier=" + tier.tier + " " + ex)); } } if (pending.Count == 0) { yield break; } string[] array3 = new string[3] { "LoaderHook", "LoaderYankHook", "LoaderPylon" }; foreach (string kind in array3) { GameObject prefab = null; IEnumerator load = Load<GameObject>((object)("RoR2/Base/Loader/" + kind + ".prefab"), (Action<GameObject>)delegate(GameObject p) { prefab = p; }); while (load.MoveNext()) { yield return null; } ProjectileController component = prefab.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Loader projectile controller missing"); } ProjectileKinds[component.catalogIndex] = kind; } array = (GameObject[])(object)new GameObject[2] { model, display }; foreach (GameObject val9 in array) { (val9.GetComponent<LoaderVisualRig>() ?? val9.AddComponent<LoaderVisualRig>()).Configure(val9.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null).Single((SkinnedMeshRenderer r) => ((Object)r).name == "PilotFemaleMesh")); } foreach (LoaderDefinition item in pending) { ByMesh.Add(item.Body, item); BySkin.Add(item.Rig.skinId, item); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_LOADER_TIER_READY tier=" + item.Tier + " name=" + item.Name)); } ctrl.skins = next.ToArray(); registered = true; ProjectileController.Start += new hook_Start(ProjectileStart); SyncDisplay(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_LOADER_REGISTERED count=" + pending.Count + " version=0.2.0")); } private void SyncDisplay() { if (registered && Object.op_Implicit((Object)(object)display) && Object.op_Implicit((Object)(object)model)) { (display.GetComponent<ModelSkinController>() ?? display.AddComponent<ModelSkinController>()).skins = (SkinDef[])model.GetComponent<ModelSkinController>().skins.Clone(); } } private void ProjectileStart(orig_Start orig, ProjectileController self) { orig.Invoke(self); if (Object.op_Implicit((Object)(object)self) && ProjectileKinds.ContainsKey(self.catalogIndex)) { (((Component)self).GetComponent<LoaderProjectileVisual>() ?? ((Component)self).gameObject.AddComponent<LoaderProjectileVisual>()).Configure(self, ProjectileKinds[self.catalogIndex]); } } private static Texture2D Texture(string path) { //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_0025: Expected O, but got Unknown //IL_0033: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false) { anisoLevel = 4, filterMode = (FilterMode)2 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path), false)) { throw new InvalidDataException("Loader image decode failed"); } return val; } private static void ValidateRig(LoaderRig r, int tier) { if (r == null || r.schema != 1 || r.tier != tier || r.skinId != "EclipseLoaderE" + tier || r.bones == null || r.bones.Length != 136) { throw new InvalidDataException("Loader rig identity"); } HashSet<string> hashSet = new HashSet<string>(); for (int i = 0; i < r.bones.Length; i++) { LoaderBone loaderBone = r.bones[i]; if (loaderBone == null || !hashSet.Add(loaderBone.name) || loaderBone.parent >= i || loaderBone.parent < -1) { throw new InvalidDataException("Loader rig hierarchy"); } float[][] array = new float[4][] { loaderBone.position, loaderBone.scale, loaderBone.nativePosition, loaderBone.nativeScale }; foreach (float[] array2 in array) { if (array2 == null || array2.Length != 3 || array2.Any((float x) => float.IsNaN(x) || float.IsInfinity(x))) { throw new InvalidDataException("Loader rig vector"); } } array = new float[2][] { loaderBone.rotation, loaderBone.nativeRotation }; foreach (float[] array3 in array) { if (array3 == null || array3.Length != 4 || array3.Any((float x) => float.IsNaN(x) || float.IsInfinity(x)) || (double)Math.Abs(array3.Sum((float x) => x * x) - 1f) > 0.005) { throw new InvalidDataException("Loader rig quaternion"); } } if (loaderBone.bindpose == null || loaderBone.bindpose.Length != 16 || loaderBone.bindpose.Any((float x) => float.IsNaN(x) || float.IsInfinity(x)) || loaderBone.nativeScale.Any((float x) => (double)Math.Abs(x) < 1E-06)) { throw new InvalidDataException("Loader rig bind pose"); } } } private static Mesh ReadMesh(string path, LoaderRig rig) { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0398: 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_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_0345: 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) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Loader 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 != ((rig == null) ? 1 : 136)) { throw new InvalidDataException("Loader mesh dimensions"); } for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Loader bone length"); } if (Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)) != ((rig == null) ? "root" : rig.bones[i].name)) { throw new InvalidDataException("Loader mesh bone slot"); } } if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position != 64L * (long)num + 4L * (long)num2) { throw new InvalidDataException("Loader mesh length"); } Vector3[] array = (Vector3[])(object)new Vector3[num]; Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector2[] array3 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array4 = (BoneWeight[])(object)new BoneWeight[num]; for (int j = 0; j < num; j++) { array[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[j] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array5 = new int[4]; float[] array6 = new float[4]; for (int k = 0; k < 4; k++) { array5[k] = binaryReader.ReadInt32(); if (array5[k] < 0 || array5[k] >= num3) { throw new InvalidDataException("Loader weight bone"); } } for (int l = 0; l < 4; l++) { array6[l] = binaryReader.ReadSingle(); } if (!Finite(array[j]) || !Finite(array2[j]) || float.IsNaN(array3[j].x + array3[j].y) || float.IsInfinity(array3[j].x + array3[j].y) || (double)Math.Abs(((Vector3)(ref array2[j])).magnitude - 1f) > 0.002 || array6.Any((float x) => float.IsNaN(x) || float.IsInfinity(x) || x < 0f) || (double)Math.Abs(array6.Sum() - 1f) > 0.002) { throw new InvalidDataException("Loader vertex attributes"); } int num5 = j; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array5[0]; ((BoneWeight)(ref val)).boneIndex1 = array5[1]; ((BoneWeight)(ref val)).boneIndex2 = array5[2]; ((BoneWeight)(ref val)).boneIndex3 = array5[3]; ((BoneWeight)(ref val)).weight0 = array6[0]; ((BoneWeight)(ref val)).weight1 = array6[1]; ((BoneWeight)(ref val)).weight2 = array6[2]; ((BoneWeight)(ref val)).weight3 = array6[3]; array4[num5] = val; } int[] array7 = new int[num2]; for (int num6 = 0; num6 < num2; num6++) { array7[num6] = binaryReader.ReadInt32(); if (array7[num6] < 0 || array7[num6] >= num) { throw new InvalidDataException("Loader mesh index"); } } Mesh val2 = new Mesh { name = Path.GetFileName(path), indexFormat = (IndexFormat)1 }; val2.vertices = array; val2.normals = array2; val2.uv = array3; val2.triangles = array7; if (rig != null) { val2.boneWeights = array4; Matrix4x4[] array8 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num7 = 0; num7 < num3; num7++) { for (int num8 = 0; num8 < 4; num8++) { for (int num9 = 0; num9 < 4; num9++) { ((Matrix4x4)(ref array8[num7]))[num8, num9] = rig.bones[num7].bindpose[num8 * 4 + num9]; } } } val2.bindposes = array8; } val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } 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; } private void OnDestroy() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplay)); MainMenuController.OnMainMenuInitialised -= SyncDisplay; ProjectileController.Start -= new hook_Start(ProjectileStart); if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } internal sealed class LoaderGorillaGait { private readonly Transform space; private readonly Transform[] bones; private readonly Transform[] native; private readonly LoaderRig rig; private readonly CharacterBody body; private readonly Animator animator; private readonly int[] upper = new int[2]; private readonly int[] lower = new int[2]; private readonly int[] hand = new int[2]; private readonly Vector3[] restHand = (Vector3[])(object)new Vector3[2]; private readonly Quaternion[] restHandRotation = (Quaternion[])(object)new Quaternion[2]; private readonly EntityStateMachine[] machines = (EntityStateMachine[])(object)new EntityStateMachine[4]; private readonly int[] layers = new int[7]; private float weight; private static readonly string[] MachineNames = new string[4] { "Body", "Weapon", "Hook", "Pylon" }; private static readonly string[] LayerNames = new string[7] { "Body", "Grapple", "Gesture, Additive", "Gesture, Override", "FullBody, Override", "Flinch", "Impact" }; public LoaderGorillaGait(Transform model, Transform rendererSpace, Transform[] visual, Transform[] source, LoaderRig definition) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) space = rendererSpace; bones = visual; native = source; rig = definition; body = ((Component)model).GetComponentInParent<CharacterBody>(); animator = ((Component)model).GetComponent<Animator>(); for (int i = 0; i < 2; i++) { string text = ((i == 0) ? "l" : "r"); upper[i] = Find("mech.upper_arm." + text); lower[i] = Find("mech.lower_arm." + text); hand[i] = Find("mech.hand." + text); LoaderBone loaderBone = rig.bones[hand[i]]; Matrix4x4 val = default(Matrix4x4); for (int j = 0; j < 16; j++) { ((Matrix4x4)(ref val))[j / 4, j % 4] = loaderBone.bindpose[j]; } val = ((Matrix4x4)(ref val)).inverse; restHand[i] = Vector4.op_Implicit(((Matrix4x4)(ref val)).GetColumn(3)); restHandRotation[i] = ((Matrix4x4)(ref val)).rotation; } if (Object.op_Implicit((Object)(object)body)) { for (int k = 0; k < 4; k++) { machines[k] = EntityStateMachine.FindByCustomName(((Component)body).gameObject, MachineNames[k]); } } for (int l = 0; l < layers.Length; l++) { layers[l] = (Object.op_Implicit((Object)(object)animator) ? animator.GetLayerIndex(LayerNames[l]) : (-1)); } } private int Find(string name) { for (int i = 0; i < rig.bones.Length; i++) { if (rig.bones[i].name == name) { return i; } } throw new InvalidOperationException("Missing gorilla bone " + name); } private bool AllowedState(AnimatorStateInfo state, int layer) { if (layer == 0) { if (!((AnimatorStateInfo)(ref state)).IsName("Body.Idle") && !((AnimatorStateInfo)(ref state)).IsName("Body.IdleIn")) { return ((AnimatorStateInfo)(ref state)).IsName("Body.Run"); } return true; } if (!((AnimatorStateInfo)(ref state)).IsName(LayerNames[layer] + ".Empty")) { return ((AnimatorStateInfo)(ref state)).IsName(LayerNames[layer] + ".BufferEmpty"); } return true; } private bool GroundedGate() { //IL_0212: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive || !Object.op_Implicit((Object)(object)body.characterMotor) || !((Behaviour)body.characterMotor).isActiveAndEnabled || !body.characterMotor.isGrounded || body.characterMotor.isFlying || !Object.op_Implicit((Object)(object)animator)) { return false; } for (int i = 0; i < 4; i++) { if (!Object.op_Implicit((Object)(object)machines[i]) || !machines[i].IsInMainState() || machines[i].HasPendingState()) { return false; } } if (!(machines[0].state is GenericCharacterMain)) { return false; } for (int j = 1; j < 4; j++) { if (((object)machines[j].state).GetType() != typeof(Idle)) { return false; } } if (body.hasEffectiveAuthority && Object.op_Implicit((Object)(object)body.inputBank)) { InputBankTest inputBank = body.inputBank; if (inputBank.jump.down || ((ButtonState)(ref inputBank.jump)).justPressed || inputBank.skill1.down || ((ButtonState)(ref inputBank.skill1)).justPressed || inputBank.skill2.down || ((ButtonState)(ref inputBank.skill2)).justPressed || inputBank.skill3.down || ((ButtonState)(ref inputBank.skill3)).justPressed || inputBank.skill4.down || ((ButtonState)(ref inputBank.skill4)).justPressed || inputBank.activateEquipment.down || ((ButtonState)(ref inputBank.activateEquipment)).justPressed) { return false; } } for (int k = 0; k < layers.Length; k++) { if (layers[k] < 0 || animator.IsInTransition(layers[k]) || !AllowedState(animator.GetCurrentAnimatorStateInfo(layers[k]), k)) { return false; } } return true; } public void Apply() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: 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) if (!Object.op_Implicit((Object)(object)body)) { for (int i = 0; i < 2; i++) { Solve(i, space.TransformPoint(restHand[i]), space.rotation * restHandRotation[i]); } return; } if (!Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive) { weight = 0f; return; } bool flag = GroundedGate(); weight = (flag ? Mathf.MoveTowards(weight, 1f, Time.deltaTime * 6f) : 0f); float num = (Object.op_Implicit((Object)(object)body.characterMotor) ? Mathf.Clamp01(((Vector3)(ref body.characterMotor.velocity)).magnitude / Mathf.Max(1f, body.moveSpeed)) : 0f); float num2; if (!flag) { num2 = 0f; } else { AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(layers[0]); num2 = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime; } float num3 = num2; for (int j = 0; j < 2; j++) { Quaternion rotation = bones[hand[j]].rotation; Vector3 position = native[hand[j]].position; if (weight > 0f) { float num4 = Mathf.Repeat(num3 + (float)j * 0.5f, 1f); float num5; float num6; if (num4 < 0.6f) { num5 = Mathf.Lerp(-0.14f, 0.14f, num4 / 0.6f); num6 = 0f; } else { float num7 = (num4 - 0.6f) / 0.4f; num5 = Mathf.Lerp(0.14f, -0.14f, num7); num6 = Mathf.Sin(num7 * (float)Math.PI) * 0.12f; } Vector3 val = space.TransformPoint(restHand[j] + new Vector3(0f, num5 * num, num6 * num)); Solve(j, Vector3.Lerp(position, val, weight), Quaternion.Slerp(rotation, space.rotation * restHandRotation[j], weight), planted: true); } else { Solve(j, position, rotation); } } } private void Solve(int side, Vector3 target, Quaternion orientation, bool planted = false) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) Transform val = bones[upper[side]]; Transform val2 = bones[lower[side]]; Transform val3 = bones[hand[side]]; Vector3 position = val.position; Vector3 val4 = val2.position - position; Vector3 val5 = val3.position - val2.position; Vector3 val6 = target - position; float magnitude = ((Vector3)(ref val4)).magnitude; float magnitude2 = ((Vector3)(ref val5)).magnitude; float magnitude3 = ((Vector3)(ref val6)).magnitude; if (!(magnitude < 0.001f) && !(magnitude2 < 0.001f) && !(magnitude3 < 0.001f)) { if (planted && magnitude3 > magnitude + magnitude2 - 0.0005f) { float num = Mathf.Min(1.18f, (magnitude3 + 0.001f) / (magnitude + magnitude2)); val2.position = position + val4 * num; val3.position = val2.position + val5 * num; val4 = val2.position - position; val5 = val3.position - val2.position; magnitude = ((Vector3)(ref val4)).magnitude; magnitude2 = ((Vector3)(ref val5)).magnitude; } float num2 = Mathf.Clamp(magnitude3, Mathf.Abs(magnitude - magnitude2) + 0.0005f, magnitude + magnitude2 - 0.0005f); Vector3 val7 = val6 / magnitude3; Vector3 val8 = Vector3.ProjectOnPlane(space.TransformDirection(new Vector3((side == 0) ? (-0.5f) : 0.5f, 0.4f, 0.1f)), val7); Vector3 normalized = ((Vector3)(ref val8)).normalized; if (!(((Vector3)(ref normalized)).sqrMagnitude < 0.5f)) { float num3 = (magnitude * magnitude + num2 * num2 - magnitude2 * magnitude2) / (2f * num2); float num4 = Mathf.Sqrt(Mathf.Max(0f, magnitude * magnitude - num3 * num3)); Vector3 val9 = position + val7 * num3 + normalized * num4; val.rotation = Quaternion.FromToRotation(val4, val9 - position) * val.rotation; val2.rotation = Quaternion.FromToRotation(val3.position - val2.position, position + val7 * num2 - val2.position) * val2.rotation; val3.rotation = orientation; } } } } [DefaultExecutionOrder(32000)] public sealed class LoaderProjectileVisual : MonoBehaviour { private ProjectileController projectile; private strin
BepInEx/plugins/RodaniusSkinRuntime/Eclipse.RailgunnerSkins.dll
Decompiled a day 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.Security.Cryptography; using System.Text; using BepInEx; using EntityStates; using EntityStates.Railgunner.Weapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using Rodanius.Standalone; 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 Eclipse.RailgunnerSkins { [BepInPlugin("eclipseplaytest.railgunner.collection", "Eclipse Railgunner Skins (Private Playtest)", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class RailgunnerCollection : BaseUnityPlugin { [Serializable] public sealed class Manifest { public int schema; public Tier[] tiers; } [Serializable] public sealed class Tier { public int tier; public string name; public string folder; } [Serializable] public sealed class Bone { public string name; public int parent; public float[] bindpose; } [Serializable] public sealed class Presentation { public int schema; public float[] sniperMuzzleBodyLocal; } [Serializable] public sealed class Rig { public int schema; public int tier; public string skinId; public Bone[] bones; } public const string Guid = "eclipseplaytest.railgunner.collection"; public const string Version = "0.2.0"; public static readonly HashSet<Mesh> AuthoredMeshes = new HashSet<Mesh>(); public static readonly Dictionary<Mesh, Vector3> MuzzlePositions = new Dictionary<Mesh, Vector3>(); public static bool PresentationEnabled; private bool warnedMuzzle; private bool muzzleSubscribed; private static RailgunnerCollection instance; private string folder; private float deadline; private GameObject model; private GameObject display; private bool registered; private readonly List<AsyncOperationHandle> handles = new List<AsyncOperationHandle>(); private static readonly string[] Replaced = new string[4] { "mdlRailGunnerBase", "mdlRailGunnerMetal", "mdlRailgunProto", "mdlRailgunBackpackMesh" }; private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(RailgunnerCollection)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplay)); MainMenuController.OnMainMenuInitialised += SyncDisplay; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(SurvivorCatalog) })] private static IEnumerator Initialize() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 90f; IEnumerator e = instance.Register(); try { while (true) { bool flag; try { flag = e.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ECLIPSE_RAILGUNNER_REGISTRATION_FAILED " + ex)); break; } if (flag) { yield return e.Current; continue; } break; } } finally { IDisposable disposable = e as IDisposable; if (disposable != null) { disposable.Dispose(); } } } private IEnumerator Load<T>(object key, Action<T> set) where T : Object { AsyncOperationHandle<T> op = Addressables.LoadAssetAsync<T>(key); handles.Add(AsyncOperationHandle<T>.op_Implicit(op)); while (!op.IsDone) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Railgunner loading exceeded deadline"); } yield return null; } if (!Object.op_Implicit((Object)(object)op.Result)) { throw new InvalidDataException("Missing native asset " + key); } set(op.Result); } private static SkinnedMeshRenderer Renderer(GameObject root, string name) { Transform obj = root.transform.Find(name); if (!Object.op_Implicit((Object)(object)obj)) { throw new InvalidOperationException("Required Railgunner renderer path missing: " + name); } SkinnedMeshRenderer component = ((Component)obj).GetComponent<SkinnedMeshRenderer>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Expected skinned renderer: " + name); } return component; } private IEnumerator Register() { List<SkinRecord> list = SkinDiscovery.Load("railgunner", delegate(string m) { ((BaseUnityPlugin)this).Logger.LogWarning((object)m); }); if (list.Count == 0) { yield break; } Manifest manifest = new Manifest { schema = 1, tiers = list.Select((SkinRecord r) => new Tier { tier = r.tier, name = r.name, folder = r.AssetRoot }).ToArray() }; GameObject val = BodyCatalog.FindBodyPrefab("RailgunnerBody"); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("RailgunnerBody missing"); } model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(val); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab)) { throw new InvalidOperationException("Railgunner display missing"); } display = ((Component)val2.displayPrefab.GetComponentInChildren<CharacterModel>(true)).gameObject; ModelSkinController ctrl = model.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)ctrl) || ctrl.skins == null || ctrl.skins.Length == 0) { throw new InvalidOperationException("Railgunner stock skins missing"); } SkinDef stock = ctrl.skins[0]; SkinDefParams bp = stock.skinDefParams; if (!Object.op_Implicit((Object)(object)bp)) { IEnumerator load = Load<SkinDefParams>(((AssetReference)stock.skinDefParamsAddress).RuntimeKey, (Action<SkinDefParams>)delegate(SkinDefParams v) { bp = v; }); while (load.MoveNext()) { yield return null; } } if (!Object.op_Implicit((Object)(object)bp) || bp.rendererInfos == null) { throw new InvalidDataException("Default skin parameters unavailable"); } SkinnedMeshRenderer target = Renderer(model, "mdlRailGunnerBase"); RendererInfo val3 = bp.rendererInfos.Single((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material native = val3.defaultMaterial; if (!Object.op_Implicit((Object)(object)native)) { IEnumerator load = Load<Material>(((AssetReference)val3.defaultMaterialAddress).RuntimeKey, (Action<Material>)delegate(Material v) { native = v; }); while (load.MoveNext()) { yield return null; } } if (!Object.op_Implicit((Object)(object)native) || !Object.op_Implicit((Object)(object)native.shader)) { throw new InvalidOperationException("Native body shader unavailable"); } for (int num = 0; num < bp.rendererInfos.Length; num++) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_RAILGUNNER_NATIVE_RENDERER index=" + num + " path=" + (Object.op_Implicit((Object)(object)bp.rendererInfos[num].renderer) ? ((Object)bp.rendererInfos[num].renderer).name : "null"))); } GameObject[] array = (GameObject[])(object)new GameObject[2] { model, display }; foreach (GameObject root in array) { string[] replaced = Replaced; foreach (string name in replaced) { Renderer(root, name); } Renderer(root, "mdlRailGunBackpackScreen"); } List<SkinDef> list2 = new List<SkinDef>(ctrl.skins); List<Mesh> list3 = new List<Mesh>(); HashSet<int> hashSet = new HashSet<int>(); Tier[] tiers = manifest.tiers; Vector3 val4 = default(Vector3); foreach (Tier tier in tiers) { try { if (tier.tier < 1 || tier.tier > 8 || !hashSet.Add(tier.tier) || Path.GetFileName(tier.folder) != "e" + tier.tier || string.IsNullOrEmpty(tier.name)) { throw new InvalidDataException("Tier identity"); } string path = Path.Combine(folder, tier.folder); Rig rig = JsonUtility.FromJson<Rig>(File.ReadAllText(Path.Combine(path, "rig.json"))); ValidateRig(rig, tier.tier); array = (GameObject[])(object)new GameObject[2] { model, display }; for (int num3 = 0; num3 < array.Length; num3++) { ValidateBinding(Renderer(array[num3], "mdlRailGunnerBase"), rig); } Mesh mesh = ReadMesh(Path.Combine(path, "body.meshbin"), rig); ((Object)mesh).name = rig.skinId + "_AuthoredBodyAndRifle"; Presentation presentation = JsonUtility.FromJson<Presentation>(File.ReadAllText(Path.Combine(path, "presentation.json"))); if (presentation == null || presentation.schema != 1 || presentation.sniperMuzzleBodyLocal == null || presentation.sniperMuzzleBodyLocal.Length != 3 || presentation.sniperMuzzleBodyLocal.Any((float x) => float.IsNaN(x) || float.IsInfinity(x))) { throw new InvalidDataException("Cosmetic muzzle presentation"); } ((Vector3)(ref val4))..ctor(presentation.sniperMuzzleBodyLocal[0], presentation.sniperMuzzleBodyLocal[1], presentation.sniperMuzzleBodyLocal[2]); if (((Vector3)(ref val4)).magnitude > 4f) { throw new InvalidDataException("Cosmetic muzzle bounds"); } MuzzlePositions.Add(mesh, ((Matrix4x4)(ref mesh.bindposes[104])).MultiplyPoint3x4(val4)); Material val5 = new Material(native) { name = "matEclipseRailgunnerE" + tier.tier }; val5.SetTexture("_MainTex", (Texture)(object)Texture(Path.Combine(path, "albedo.png"))); val5.SetColor("_Color", Color.white); val5.SetFloat("_NormalStrength", 0f); val5.SetFloat("_Smoothness", 0.16f); val5.SetFloat("_SpecularStrength", 0.2f); val5.SetFloat("_SpecularExponent", 8f); val5.SetFloat("_EmPower", 0f); val5.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture); val5.DisableKeyword("FLOWMAP"); val5.SetFloat("_FlowmapOn", 0f); val5.SetFloat("_FlowEmissionStrength", 0f); val5.DisableKeyword("LIMBREMOVAL"); val5.SetFloat("_LimbRemovalOn", 0f); val5.DisableKeyword("FORCE_SPEC"); val5.SetFloat("_ForceSpecOn", 0f); Mesh empty = new Mesh { name = rig.skinId + "_EmptyReplacedParts" }; empty.vertices = Array.Empty<Vector3>(); empty.triangles = Array.Empty<int>(); RendererInfo[] array2 = (RendererInfo[])bp.rendererInfos.Clone(); for (int num4 = 0; num4 < array2.Length; num4++) { if ((Object)(object)array2[num4].renderer == (Object)(object)target) { array2[num4].defaultMaterial = val5; array2[num4].defaultMaterialAddress = new AssetReferenceT<Material>(""); } } MeshReplacement[] meshReplacements = ((IEnumerable<string>)Replaced).Select((Func<string, MeshReplacement>)((string text) => new MeshReplacement { renderer = (Renderer)(object)Renderer(model, text), mesh = ((text == "mdlRailGunnerBase") ? mesh : empty), meshAddress = new AssetReferenceT<Mesh>("") })).ToArray(); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = rig.skinId + "_Params"; val6.rendererInfos = array2; val6.meshReplacements = meshReplacements; SkinDef skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = rig.skinId; skin.nameToken = "ECLIPSE_RAILGUNNER_E" + tier.tier; LanguageAPI.Add(skin.nameToken, tier.name + " (Playtest)"); skin.rootObject = model; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { stock }; skin.skinDefParams = val6; skin.unlockableDef = null; Texture2D val7 = Texture(Path.Combine(path, "icon.png")); skin.icon = Sprite.Create(val7, new Rect(0f, 0f, (float)((Texture)val7).width, (float)((Texture)val7).height), new Vector2(0.5f, 0.5f)); if (list2.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)skin).name)) { throw new InvalidOperationException("Duplicate skin " + ((Object)skin).name); } list2.Add(skin); list3.Add(mesh); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_RAILGUNNER_TIER_READY tier=" + tier.tier + " name=" + tier.name + " vertices=" + mesh.vertexCount)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("RODANIUS_RAILGUNNER_SKIN_FAILED tier=" + tier.tier + " " + ex)); } } if (list3.Count == 0) { yield break; } array = (GameObject[])(object)new GameObject[2] { model, display }; foreach (GameObject val8 in array) { (val8.GetComponent<RailgunnerBounds>() ?? val8.AddComponent<RailgunnerBounds>()).Configure(Renderer(val8, "mdlRailGunnerBase")); (val8.GetComponent<RailgunnerMuzzle>() ?? val8.AddComponent<RailgunnerMuzzle>()).Configure(Renderer(val8, "mdlRailGunnerBase"), val8.GetComponent<ChildLocator>()); } foreach (Mesh item in list3) { AuthoredMeshes.Add(item); } ctrl.skins = list2.ToArray(); registered = true; OnEnable(); SyncDisplay(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_RAILGUNNER_REGISTERED count=" + list3.Count + " version=0.2.0")); } private void OnEnable() { if (registered) { PresentationEnabled = true; if (!muzzleSubscribed) { BaseFireSnipe.onFireSnipe += AdaptSniperMuzzle; muzzleSubscribed = true; } } } private void OnDisable() { PresentationEnabled = false; if (muzzleSubscribed) { BaseFireSnipe.onFireSnipe -= AdaptSniperMuzzle; muzzleSubscribed = false; } RailgunnerMuzzle[] array = Object.FindObjectsOfType<RailgunnerMuzzle>(); for (int i = 0; i < array.Length; i++) { array[i].Release(); } RailgunnerBounds[] array2 = Object.FindObjectsOfType<RailgunnerBounds>(); for (int i = 0; i < array2.Length; i++) { array2[i].Release(); } } internal static void ReportMuzzleValidation(string reason) { if (Object.op_Implicit((Object)(object)instance)) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("ECLIPSE_RAILGUNNER_MUZZLE_VALIDATION_SKIPPED " + reason)); } } private void AdaptSniperMuzzle(BaseFireSnipe state) { try { Type type = ((object)state).GetType(); if ((type != typeof(FireSnipeHeavy) && type != typeof(FireSnipeLight) && type != typeof(FireSnipeSuper) && type != typeof(FireSnipeCryo)) || (((GenericBulletBaseState)state).muzzleName != "MuzzleRight" && ((GenericBulletBaseState)state).muzzleName != "MuzzleSniper") || !Object.op_Implicit((Object)(object)((EntityState)state).outer)) { return; } ModelLocator component = ((Component)((EntityState)state).outer).GetComponent<ModelLocator>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.modelTransform)) { RailgunnerMuzzle component2 = ((Component)component.modelTransform).GetComponent<RailgunnerMuzzle>(); if (Object.op_Implicit((Object)(object)component2) && ((Behaviour)component2).isActiveAndEnabled && component2.Ensure()) { component2.Remember(state); ((GenericBulletBaseState)state).muzzleName = "MuzzleSniper"; } } } catch (Exception ex) { if (!warnedMuzzle) { warnedMuzzle = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("ECLIPSE_RAILGUNNER_COSMETIC_MUZZLE_SKIPPED " + ex.Message)); } } } private void SyncDisplay() { if (registered && Object.op_Implicit((Object)(object)display) && Object.op_Implicit((Object)(object)model)) { (display.GetComponent<ModelSkinController>() ?? display.AddComponent<ModelSkinController>()).skins = (SkinDef[])model.GetComponent<ModelSkinController>().skins.Clone(); } } private static Texture2D Texture(string path) { //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_0025: Expected O, but got Unknown //IL_0033: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false) { anisoLevel = 4, filterMode = (FilterMode)2 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path), false)) { throw new InvalidDataException("Image decode failed"); } return val; } private static void ValidateRig(Rig r, int tier) { if (r == null || r.schema != 1 || r.tier != tier || r.skinId != "EclipseRailgunnerE" + tier || r.bones == null || r.bones.Length != 154) { throw new InvalidDataException("Rig identity"); } HashSet<string> hashSet = new HashSet<string>(); for (int i = 0; i < r.bones.Length; i++) { Bone bone = r.bones[i]; if (bone == null || string.IsNullOrEmpty(bone.name) || !hashSet.Add(bone.name) || bone.parent >= i || bone.parent < -1 || bone.bindpose == null || bone.bindpose.Length != 16 || bone.bindpose.Any((float x) => float.IsNaN(x) || float.IsInfinity(x))) { throw new InvalidDataException("Rig hierarchy/bindpose"); } } } private static void ValidateBinding(SkinnedMeshRenderer r, Rig rig) { if (r.bones.Length != 154) { throw new InvalidOperationException("Railgunner native bone count changed"); } for (int i = 0; i < 154; i++) { Transform val = r.bones[i]; if (!Object.op_Implicit((Object)(object)val) || ((Object)val).name != rig.bones[i].name) { throw new InvalidOperationException("Railgunner ordered bone mismatch " + i); } int parent = rig.bones[i].parent; if (parent >= 0 && (Object)(object)val.parent != (Object)(object)r.bones[parent]) { throw new InvalidOperationException("Railgunner native ancestry mismatch " + i); } } } private static Mesh ReadMesh(string path, Rig rig) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0337: 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)) != "PWE1") { throw new InvalidDataException("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 != 154) { throw new InvalidDataException("Mesh dimensions"); } for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Bone length"); } if (Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)) != rig.bones[i].name) { throw new InvalidDataException("Mesh bone slot"); } } if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position != 64L * (long)num + 4L * (long)num2) { throw new InvalidDataException("Mesh length"); } Vector3[] array = (Vector3[])(object)new Vector3[num]; Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector2[] array3 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array4 = (BoneWeight[])(object)new BoneWeight[num]; for (int j = 0; j < num; j++) { array[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[j] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array5 = new int[4]; float[] array6 = new float[4]; for (int k = 0; k < 4; k++) { array5[k] = binaryReader.ReadInt32(); if (array5[k] < 0 || array5[k] >= num3) { throw new InvalidDataException("Weight bone"); } } for (int l = 0; l < 4; l++) { array6[l] = binaryReader.ReadSingle(); } if (!Finite(array[j]) || !Finite(array2[j]) || float.IsNaN(array3[j].x + array3[j].y) || float.IsInfinity(array3[j].x + array3[j].y) || (double)Math.Abs(((Vector3)(ref array2[j])).magnitude - 1f) > 0.002 || array6.Any((float x) => float.IsNaN(x) || float.IsInfinity(x) || x < 0f) || (double)Math.Abs(array6.Sum() - 1f) > 0.002) { throw new InvalidDataException("Vertex attributes"); } int num5 = j; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array5[0]; ((BoneWeight)(ref val)).boneIndex1 = array5[1]; ((BoneWeight)(ref val)).boneIndex2 = array5[2]; ((BoneWeight)(ref val)).boneIndex3 = array5[3]; ((BoneWeight)(ref val)).weight0 = array6[0]; ((BoneWeight)(ref val)).weight1 = array6[1]; ((BoneWeight)(ref val)).weight2 = array6[2]; ((BoneWeight)(ref val)).weight3 = array6[3]; array4[num5] = val; } int[] array7 = new int[num2]; for (int num6 = 0; num6 < num2; num6++) { array7[num6] = binaryReader.ReadInt32(); if (array7[num6] < 0 || array7[num6] >= num) { throw new InvalidDataException("Mesh index"); } } Mesh val2 = new Mesh { name = Path.GetFileName(path), indexFormat = (IndexFormat)1 }; val2.vertices = array; val2.normals = array2; val2.uv = array3; val2.triangles = array7; val2.boneWeights = array4; Matrix4x4[] array8 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num7 = 0; num7 < num3; num7++) { for (int num8 = 0; num8 < 4; num8++) { for (int num9 = 0; num9 < 4; num9++) { ((Matrix4x4)(ref array8[num7]))[num8, num9] = rig.bones[num7].bindpose[num8 * 4 + num9]; } } } val2.bindposes = array8; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } 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; } private void OnDestroy() { BaseFireSnipe.onFireSnipe -= AdaptSniperMuzzle; RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplay)); MainMenuController.OnMainMenuInitialised -= SyncDisplay; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } [DefaultExecutionOrder(31900)] public sealed class RailgunnerBounds : MonoBehaviour { [SerializeField] private SkinnedMeshRenderer target; [SerializeField] private Bounds original; [SerializeField] private bool originalOffscreen; private bool changed; public void Configure(SkinnedMeshRenderer r) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) target = r; original = ((Renderer)r).localBounds; originalOffscreen = r.updateWhenOffscreen; } private void LateUpdate() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)target)) { if (RailgunnerCollection.PresentationEnabled && RailgunnerCollection.AuthoredMeshes.Contains(target.sharedMesh)) { SkinnedMeshRenderer obj = target; Bounds bounds = target.sharedMesh.bounds; Vector3 center = ((Bounds)(ref bounds)).center; bounds = target.sharedMesh.bounds; ((Renderer)obj).localBounds = new Bounds(center, ((Bounds)(ref bounds)).size + Vector3.one * 3f); target.updateWhenOffscreen = true; changed = true; } else { Restore(); } } } public void Release() { Restore(); } private void Restore() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (changed && Object.op_Implicit((Object)(object)target)) { ((Renderer)target).localBounds = original; target.updateWhenOffscreen = originalOffscreen; } changed = false; } private void OnDisable() { Restore(); } private void OnDestroy() { Restore(); } } [DefaultExecutionOrder(-32000)] public sealed class RailgunnerMuzzle : MonoBehaviour { [SerializeField] private SkinnedMeshRenderer target; [SerializeField] private ChildLocator locator; [SerializeField] private Transform leaf; [SerializeField] private Transform parent; [SerializeField] private Vector3 originalPosition; private Vector3 lastWrittenPosition; private bool changed; private bool warnedValidation; private readonly List<Tuple<WeakReference<BaseFireSnipe>, string>> touched = new List<Tuple<WeakReference<BaseFireSnipe>, string>>(); private void WarnValidation() { if (!warnedValidation) { warnedValidation = true; RailgunnerCollection.ReportMuzzleValidation("Expected existing MuzzleSniper index3 beneath GunEnd; native locator left unchanged on " + ((Object)((Component)this).gameObject).name); } } public void Configure(SkinnedMeshRenderer r, ChildLocator c) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) target = r; locator = c; if (!Object.op_Implicit((Object)(object)r) || r.bones.Length <= 104 || !Object.op_Implicit((Object)(object)c)) { WarnValidation(); return; } parent = r.bones[104]; leaf = c.FindChild("MuzzleSniper"); if (!Object.op_Implicit((Object)(object)leaf) || (Object)(object)leaf.parent != (Object)(object)parent || c.FindChildIndex("MuzzleSniper") != 3) { leaf = null; WarnValidation(); } else { originalPosition = leaf.localPosition; } } public bool Ensure() { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (!((Behaviour)this).isActiveAndEnabled || !RailgunnerCollection.PresentationEnabled || !Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)target.sharedMesh) || !RailgunnerCollection.MuzzlePositions.TryGetValue(target.sharedMesh, out var value)) { Restore(); return false; } if (!Object.op_Implicit((Object)(object)leaf) || !Object.op_Implicit((Object)(object)parent) || (Object)(object)leaf.parent != (Object)(object)parent || !Object.op_Implicit((Object)(object)locator) || locator.FindChildIndex("MuzzleSniper") != 3 || (Object)(object)locator.FindChild("MuzzleSniper") != (Object)(object)leaf) { WarnValidation(); Restore(); return false; } leaf.localPosition = value; lastWrittenPosition = value; changed = true; return true; } public void Remember(BaseFireSnipe state) { if (!(((GenericBulletBaseState)state).muzzleName == "MuzzleSniper")) { touched.Add(Tuple.Create(new WeakReference<BaseFireSnipe>(state), ((GenericBulletBaseState)state).muzzleName)); } } public void Release() { Restore(); } private void Prune() { for (int num = touched.Count - 1; num >= 0; num--) { if (!touched[num].Item1.TryGetTarget(out var val) || (Object)(object)((EntityState)val).outer == (Object)null || (object)((EntityState)val).outer.state != val) { touched.RemoveAt(num); } } } private void OnEnable() { Ensure(); } private void Update() { Ensure(); Prune(); } private void FixedUpdate() { Ensure(); } private void LateUpdate() { Ensure(); } private void Restore() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (changed && Object.op_Implicit((Object)(object)leaf) && (Object)(object)leaf.parent == (Object)(object)parent) { Vector3 val = leaf.localPosition - lastWrittenPosition; if (((Vector3)(ref val)).sqrMagnitude < 1E-12f) { leaf.localPosition = originalPosition; } } changed = false; foreach (Tuple<WeakReference<BaseFireSnipe>, string> item in touched) { if (item.Item1.TryGetTarget(out var val2) && ((GenericBulletBaseState)val2).muzzleName == "MuzzleSniper") { ((GenericBulletBaseState)val2).muzzleName = item.Item2; } } touched.Clear(); } private void OnDisable() { Restore(); } private void OnDestroy() { Restore(); } } } namespace Rodanius.Standalone { public static class CatalogueSpecs { public static bool Matches(SkinRecord r) { switch (r.key) { case "acrid-bog-hopper": if (r.skinId == "EclipsePlaytestAcridE1BogHopper" && r.family == "single" && r.name == "Bog Hopper" && r.survivor == "Acrid") { return r.tier == 1; } return false; case "acrid-duck-and-cover": if (r.skinId == "EclipsePlaytestAcridE2DuckAndCover" && r.family == "single" && r.name == "Duck and Cover" && r.survivor == "Acrid") { return r.tier == 2; } return false; case "acrid-trash-panda": if (r.skinId == "EclipsePlaytestAcridE3TrashPanda" && r.family == "single" && r.name == "Trash Panda" && r.survivor == "Acrid") { return r.tier == 3; } return false; case "acrid-good-boy": if (r.skinId == "EclipsePlaytestAcridE4GoodBoy" && r.family == "single" && r.name == "Good Boy" && r.survivor == "Acrid") { return r.tier == 4; } return false; case "acrid-ginger-cat": if (r.skinId == "EclipsePlaytestAcridE5GingerCat" && r.family == "single" && r.name == "Ginger Cat" && r.survivor == "Acrid") { return r.tier == 5; } return false; case "acrid-squirrel": if (r.skinId == "EclipsePlaytestAcridE6Squirrel" && r.family == "single" && r.name == "Squirrel" && r.survivor == "Acrid") { return r.tier == 6; } return false; case "acrid-goat": if (r.skinId == "EclipsePlaytestAcridE7Goat" && r.family == "single" && r.name == "Goat" && r.survivor == "Acrid") { return r.tier == 7; } return false; case "acrid-abyssal-angler": if (r.skinId == "EclipsePlaytestAcridE8AbyssalAngler" && r.family == "single" && r.name == "Abyssal Angler" && r.survivor == "Acrid") { return r.tier == 8; } return false; case "bandit-corner-crew": if (r.skinId == "skinEclipsePlaytestBanditE1" && r.family == "single" && r.name == "Corner Crew" && r.survivor == "Bandit") { return r.tier == 1; } return false; case "bandit-after-hours": if (r.skinId == "skinEclipsePlaytestBanditE2" && r.family == "single" && r.name == "After Hours" && r.survivor == "Bandit") { return r.tier == 2; } return false; case "bandit-house-always-wins": if (r.skinId == "skinEclipsePlaytestBanditE3" && r.family == "single" && r.name == "House Always Wins" && r.survivor == "Bandit") { return r.tier == 3; } return false; case "bandit-card-shark": if (r.skinId == "skinEclipsePlaytestBanditE5" && r.family == "single" && r.name == "Card Shark" && r.survivor == "Bandit") { return r.tier == 5; } return false; case "chef-crab-rangoon": if (r.skinId == "EclipsePlaytestChefE2CrabRangoon" && r.family == "single" && r.name == "Crab Rangoon" && r.survivor == "CHEF") { return r.tier == 1; } return false; case "commando-frontier-recruit": if (r.skinId == "skinEclipsePlaytestCommandoE1" && r.family == "single" && r.name == "Frontier Recruit" && r.survivor == "Commando") { return r.tier == 1; } return false; case "commando-vacuum-breacher": if (r.skinId == "skinEclipsePlaytestCommandoE2" && r.family == "single" && r.name == "Vacuum Breacher" && r.survivor == "Commando") { return r.tier == 2; } return false; case "commando-expedition-marshal": if (r.skinId == "skinEclipsePlaytestCommandoE3" && r.family == "single" && r.name == "Expedition Marshal" && r.survivor == "Commando") { return r.tier == 3; } return false; case "commando-clockwork-infantry": if (r.skinId == "skinEclipsePlaytestCommandoE4" && r.family == "single" && r.name == "Clockwork Infantry" && r.survivor == "Commando") { return r.tier == 4; } return false; case "commando-action-figure": if (r.skinId == "skinEclipsePlaytestCommandoE5" && r.family == "single" && r.name == "Action Figure" && r.survivor == "Commando") { return r.tier == 5; } return false; case "commando-quartermaster": if (r.skinId == "skinEclipsePlaytestCommandoE6" && r.family == "single" && r.name == "Quartermaster" && r.survivor == "Commando") { return r.tier == 6; } return false; case "commando-one-man-band": if (r.skinId == "skinEclipsePlaytestCommandoE7" && r.family == "single" && r.name == "One-Man Band" && r.survivor == "Commando") { return r.tier == 7; } return false; case "commando-extinction-protocol": if (r.skinId == "skinEclipsePlaytestCommandoE8" && r.family == "single" && r.name == "Extinction Protocol" && r.survivor == "Commando") { return r.tier == 8; } return false; case "drifter-happy-camper": if (r.skinId == "EclipsePlaytestDrifterE1HappyCamper" && r.family == "single" && r.name == "Happy Camper" && r.survivor == "Drifter") { return r.tier == 1; } return false; case "engineer-union-builder": if (r.skinId == "skinEclipsePlaytestEngineerE1_union-builder" && r.family == "single" && r.name == "Union Builder" && r.survivor == "Engineer") { return r.tier == 1; } return false; case "engineer-mine-surveyor": if (r.skinId == "skinEclipsePlaytestEngineerE2_mine-surveyor" && r.family == "single" && r.name == "Mine Surveyor" && r.survivor == "Engineer") { return r.tier == 2; } return false; case "false-son-penguin": if (r.skinId == "EclipsePlaytestFalseSonE3Penguin" && r.family == "single" && r.name == "Penguin" && r.survivor == "False Son") { return r.tier == 1; } return false; case "huntress-hare-trigger": if (r.skinId == "skinEclipseHuntressNewSkins_hare-trigger" && r.family == "huntress" && r.name == "Hare Trigger" && r.survivor == "Huntress") { return r.tier == 1; } return false; case "huntress-pink-slip": if (r.skinId == "skinEclipseHuntressNewSkins_pink-slip" && r.family == "huntress" && r.name == "Pink Slip" && r.survivor == "Huntress") { return r.tier == 2; } return false; case "huntress-wallflower": if (r.skinId == "skinEclipseHuntressNewSkins_wallflower" && r.family == "huntress" && r.name == "Wallflower" && r.survivor == "Huntress") { return r.tier == 3; } return false; case "huntress-shell-shock": if (r.skinId == "skinEclipseHuntressNewSkins_shell-shock" && r.family == "huntress" && r.name == "Shell Shock" && r.survivor == "Huntress") { return r.tier == 4; } return false; case "huntress-hot-pursuit": if (r.skinId == "skinEclipseHuntressNewSkins_hot-pursuit" && r.family == "huntress" && r.name == "Hot Pursuit" && r.survivor == "Huntress") { return r.tier == 5; } return false; case "huntress-banana": if (r.skinId == "skinHuntressLiquidAssetsPlaytest_liquid-assets" && r.family == "single" && r.name == "Banana" && r.survivor == "Huntress") { return r.tier == 6; } return false; case "huntress-loose-ends": if (r.skinId == "skinEclipseHuntressNewSkins_loose-ends" && r.family == "huntress" && r.name == "Loose Ends" && r.survivor == "Huntress") { return r.tier == 7; } return false; case "huntress-dawnstrider": if (r.skinId == "skinEclipseHuntressNewSkins_dawnstrider" && r.family == "huntress" && r.name == "Dawnstrider" && r.survivor == "Huntress") { return r.tier == 8; } return false; case "loader-go-fetch": if (r.skinId == "EclipseLoaderE1" && r.family == "loader" && r.name == "Go Fetch" && r.survivor == "Loader") { return r.tier == 1; } return false; case "loader-bear-knuckle": if (r.skinId == "EclipseLoaderE2" && r.family == "loader" && r.name == "Bear Knuckle" && r.survivor == "Loader") { return r.tier == 2; } return false; case "loader-knuckle-dragger": if (r.skinId == "EclipseLoaderE3" && r.family == "loader" && r.name == "Knuckle Dragger" && r.survivor == "Loader") { return r.tier == 3; } return false; case "loader-brick-house": if (r.skinId == "EclipseLoaderE4" && r.family == "loader" && r.name == "Brick House" && r.survivor == "Loader") { return r.tier == 4; } return false; case "loader-dead-weight": if (r.skinId == "EclipseLoaderE5" && r.family == "loader" && r.name == "Dead Weight" && r.survivor == "Loader") { return r.tier == 5; } return false; case "loader-rubber-bandit": if (r.skinId == "EclipseLoaderE6" && r.family == "loader" && r.name == "Rubber Bandit" && r.survivor == "Loader") { return r.tier == 6; } return false; case "loader-high-five": if (r.skinId == "EclipseLoaderE7" && r.family == "loader" && r.name == "High Five" && r.survivor == "Loader") { return r.tier == 7; } return false; case "loader-titan-champion": if (r.skinId == "EclipseLoaderE8" && r.family == "loader" && r.name == "Titan Champion" && r.survivor == "Loader") { return r.tier == 8; } return false; case "mul-t-yard-salvager": if (r.skinId == "skinEclipsePlaytest_MULT_E1" && r.family == "single" && r.name == "Yard Salvager" && r.survivor == "MUL-T") { return r.tier == 1; } return false; case "mul-t-timber-hauler": if (r.skinId == "skinEclipsePlaytest_MULT_E2" && r.family == "single" && r.name == "Timber Hauler" && r.survivor == "MUL-T") { return r.tier == 2; } return false; case "mul-t-deep-salvage-unit": if (r.skinId == "skinEclipsePlaytest_MULT_E3" && r.family == "single" && r.name == "Deep-Salvage Unit" && r.survivor == "MUL-T") { return r.tier == 3; } return false; case "mercenary-roadworn-ronin": if (r.skinId == "EclipsePlaytestMercenaryE1RoadwornRonin" && r.family == "single" && r.name == "Roadworn Ronin" && r.survivor == "Mercenary") { return r.tier == 1; } return false; case "mercenary-canopy-cutter": if (r.skinId == "EclipsePlaytestMercenaryE3CanopyCutter" && r.family == "single" && r.name == "Canopy Cutter" && r.survivor == "Mercenary") { return r.tier == 3; } return false; case "mercenary-circuit-duelist": if (r.skinId == "EclipsePlaytestMercenaryE2CircuitDuelist" && r.family == "single" && r.name == "Circuit Duelist" && r.survivor == "Mercenary") { return r.tier == 2; } return false; case "mercenary-deli-duelist": if (r.skinId == "EclipsePlaytestMercenaryE7DeliDuelist" && r.family == "single" && r.name == "Deli Duelist" && r.survivor == "Mercenary") { return r.tier == 7; } return false; case "rex-prickly-customer": if (r.skinId == "skinEclipseRexPricklyCustomer" && r.family == "single" && r.name == "Prickly Customer" && r.survivor == "REX") { return r.tier == 1; } return false; case "railgunner-hole-in-one": if (r.skinId == "EclipseRailgunnerE1" && r.family == "railgunner" && r.name == "Hole in One" && r.survivor == "Railgunner") { return r.tier == 1; } return false; case "railgunner-night-sight": if (r.skinId == "EclipseRailgunnerE2" && r.family == "railgunner" && r.name == "Night Sight" && r.survivor == "Railgunner") { return r.tier == 2; } return false; case "railgunner-ring-leader": if (r.skinId == "EclipseRailgunnerE3" && r.family == "railgunner" && r.name == "Ring Leader" && r.survivor == "Railgunner") { return r.tier == 3; } return false; case "railgunner-fire-away": if (r.skinId == "EclipseRailgunnerE4" && r.family == "railgunner" && r.name == "Fire Away" && r.survivor == "Railgunner") { return r.tier == 4; } return false; case "railgunner-point-taken": if (r.skinId == "EclipseRailgunnerE5" && r.family == "railgunner" && r.name == "Point Taken" && r.survivor == "Railgunner") { return r.tier == 5; } return false; case "railgunner-express-delivery": if (r.skinId == "EclipseRailgunnerE6" && r.family == "railgunner" && r.name == "Express Delivery" && r.survivor == "Railgunner") { return r.tier == 6; } return false; case "railgunner-last-straw": if (r.skinId == "EclipseRailgunnerE7" && r.family == "railgunner" && r.name == "Last Straw" && r.survivor == "Railgunner") { return r.tier == 7; } return false; case "railgunner-horizon-lancer": if (r.skinId == "EclipseRailgunnerE8" && r.family == "railgunner" && r.name == "Horizon Lancer" && r.survivor == "Railgunner") { return r.tier == 8; } return false; case "seeker-breaditation": if (r.skinId == "EclipsePlaytestSeekerE7Breaditation" && r.family == "single" && r.name == "Breaditation" && r.survivor == "Seeker") { return r.tier == 1; } return false; case "void-fiend-desert-castaway": if (r.skinId == "skinEclipsePlaytestVoidFiendE1" && r.family == "single" && r.name == "Desert Castaway" && r.survivor == "Void Fiend") { return r.tier == 1; } return false; case "void-fiend-live-wire": if (r.skinId == "skinEclipsePlaytestVoidFiendE2" && r.family == "single" && r.name == "Live Wire" && r.survivor == "Void Fiend") { return r.tier == 2; } return false; case "void-fiend-pressure-guest": if (r.skinId == "skinEclipsePlaytestVoidFiendE3" && r.family == "single" && r.name == "Pressure Guest" && r.survivor == "Void Fiend") { return r.tier == 3; } return false; case "void-fiend-orange-you-glad": if (r.skinId == "skinEclipsePlaytestVoidFiendE4" && r.family == "single" && r.name == "Orange You Glad" && r.survivor == "Void Fiend") { return r.tier == 4; } return false; case "void-fiend-burnt-offering": if (r.skinId == "skinEclipsePlaytestVoidFiendE5" && r.family == "single" && r.name == "Burnt Offering" && r.survivor == "Void Fiend") { return r.tier == 5; } return false; case "void-fiend-public-information": if (r.skinId == "skinEclipsePlaytestVoidFiendE6" && r.family == "single" && r.name == "Public Information" && r.survivor == "Void Fiend") { return r.tier == 6; } return false; case "void-fiend-surprise-inside": if (r.skinId == "skinEclipsePlaytestVoidFiendE7" && r.family == "single" && r.name == "Surprise Inside" && r.survivor == "Void Fiend") { return r.tier == 7; } return false; case "void-fiend-containment-impossible": if (r.skinId == "skinEclipsePlaytestVoidFiendE8" && r.family == "single" && r.name == "Containment Impossible" && r.survivor == "Void Fiend") { return r.tier == 8; } return false; default: return false; } } } [Serializable] public sealed class AssetFile { public string path; public string sha256; } [Serializable] public sealed class SkinRecord { public int schema; public int tier; public string key; public string name; public string survivor; public string family; public string skinId; public string assetDirectory; public string icon; public string iconSha256; public AssetFile[] files; [NonSerialized] public string Root; public string AssetRoot => SkinDiscovery.SafePath(Root, assetDirectory); } public static class SkinDiscovery { public static string SafePath(string root, string relative) { if (string.IsNullOrEmpty(relative) || Path.IsPathRooted(relative) || relative.Split('/', '\\').Any((string x) => x == ".." || x == "")) { throw new InvalidDataException("Invalid package-relative path"); } string text = Path.GetFullPath(root).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; string fullPath = Path.GetFullPath(Path.Combine(root, relative)); if (!fullPath.StartsWith(text, StringComparison.OrdinalIgnoreCase) && fullPath != text.TrimEnd(Path.DirectorySeparatorChar)) { throw new InvalidDataException("Package path escaped root"); } return fullPath; } private static IEnumerable<string> FindRecords(string root, Action<string> log) { Stack<string> todo = new Stack<string>(); todo.Push(root); while (todo.Count > 0) { string dir = todo.Pop(); string text = Path.Combine(dir, "rodanius-skin.json"); if (File.Exists(text)) { yield return text; } string[] directories; try { directories = Directory.GetDirectories(dir); } catch (Exception ex) { log("RODANIUS_DISCOVERY_SKIPPED " + dir + " " + ex.Message); continue; } string[] array = directories; foreach (string text2 in array) { try { if ((File.GetAttributes(text2) & FileAttributes.ReparsePoint) == 0) { todo.Push(text2); } } catch (Exception ex2) { log("RODANIUS_DISCOVERY_SKIPPED " + ex2.Message); } } } } public static string Hash(string path) { using FileStream inputStream = File.OpenRead(path); using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant(); } public static List<SkinRecord> Load(string family, Action<string> log, bool verifyAssets = true) { List<SkinRecord> list = new List<SkinRecord>(); foreach (string item in FindRecords(Paths.PluginPath, log)) { try { if (new FileInfo(item).Length > 262144) { throw new InvalidDataException("Manifest too large"); } SkinRecord skinRecord = JsonUtility.FromJson<SkinRecord>(File.ReadAllText(item)); if (skinRecord == null || skinRecord.schema != 1 || !CatalogueSpecs.Matches(skinRecord)) { throw new InvalidDataException("Unknown standalone skin identity"); } if (family != null && skinRecord.family != family) { continue; } skinRecord.Root = Path.GetDirectoryName(item); SafePath(skinRecord.Root, skinRecord.assetDirectory); SafePath(skinRecord.Root, skinRecord.icon); if (verifyAssets) { if (skinRecord.files == null || skinRecord.files.Length == 0 || skinRecord.files.Length > 100) { throw new InvalidDataException("Asset inventory missing"); } AssetFile[] files = skinRecord.files; foreach (AssetFile assetFile in files) { if (assetFile == null || assetFile.sha256 == null || assetFile.sha256.Length != 64 || Hash(SafePath(skinRecord.Root, assetFile.path)) != assetFile.sha256) { throw new InvalidDataException("Asset hash mismatch: " + ((assetFile == null) ? "null" : assetFile.path)); } } } list.Add(skinRecord); } catch (Exception ex) { log("RODANIUS_SKIN_PACKAGE_REJECTED file=" + item + " error=" + ex.Message); } } List<SkinRecord> list2 = new List<SkinRecord>(); foreach (IGrouping<string, SkinRecord> item2 in list.GroupBy<SkinRecord, string>((SkinRecord r) => r.skinId, StringComparer.Ordinal)) { if (item2.Count() != 1) { log("RODANIUS_DUPLICATE_SKIN_PACKAGE id=" + item2.Key + " paths=" + string.Join(";", item2.Select((SkinRecord r) => r.Root))); } else { list2.Add(item2.Single()); } } return list2.OrderBy<SkinRecord, string>((SkinRecord r) => r.survivor, StringComparer.Ordinal).ThenBy((SkinRecord r) => r.tier).ToList(); } } }
BepInEx/plugins/RodaniusSkinRuntime/EclipseHuntressNewSkins.dll
Decompiled a day 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.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using Rodanius.Standalone; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal sealed class HuntressMaterialProbe : MonoBehaviour { private SkinnedMeshRenderer target; private string previous; public static void Attach(SkinnedMeshRenderer renderer) { if (Object.op_Implicit((Object)(object)renderer)) { (((Component)renderer).GetComponent<HuntressMaterialProbe>() ?? ((Component)renderer).gameObject.AddComponent<HuntressMaterialProbe>()).target = renderer; } } private void Awake() { target = ((Component)this).GetComponent<SkinnedMeshRenderer>(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)target)) { target = ((Component)this).GetComponent<SkinnedMeshRenderer>(); } if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)target.sharedMesh)) { Material sharedMaterial = ((Renderer)target).sharedMaterial; Texture val = ((Object.op_Implicit((Object)(object)sharedMaterial) && sharedMaterial.HasProperty("_MainTex")) ? sharedMaterial.GetTexture("_MainTex") : null); string text = ((Object)target.sharedMesh).name + "#" + ((Object)target.sharedMesh).GetInstanceID() + " material=" + (Object.op_Implicit((Object)(object)sharedMaterial) ? (((Object)sharedMaterial).name + "#" + ((Object)sharedMaterial).GetInstanceID()) : "null") + " shader=" + ((Object.op_Implicit((Object)(object)sharedMaterial) && Object.op_Implicit((Object)(object)sharedMaterial.shader)) ? ((Object)sharedMaterial.shader).name : "null") + " albedo=" + (Object.op_Implicit((Object)(object)val) ? (((Object)val).name + "#" + ((Object)val).GetInstanceID()) : "null"); if (!(text == previous)) { previous = text; Debug.Log((object)("ECLIPSE_HUNTRESS_APPLIED mesh=" + text + " renderer=" + ((Object)target).name)); } } } private void OnDisable() { previous = null; } } internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipseHuntressRework { [BepInPlugin("eclipse.huntress.rework20261025", "Eclipse Huntress New Skins", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EclipseHuntressNewSkins : 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 = "eclipse.huntress.rework20261025"; public const string Version = "0.2.0"; private static EclipseHuntressNewSkins 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[7] { new Design("hare-trigger", "Huntress - Hare Trigger", (Color32[])(object)new Color32[4] { new Color32((byte)132, (byte)82, (byte)48, byte.MaxValue), new Color32((byte)230, (byte)205, (byte)163, byte.MaxValue), new Color32((byte)188, (byte)80, (byte)42, byte.MaxValue), new Color32((byte)57, (byte)40, (byte)27, byte.MaxValue) }), new Design("pink-slip", "Huntress - Pink Slip", (Color32[])(object)new Color32[4] { new Color32((byte)244, (byte)107, (byte)128, byte.MaxValue), new Color32(byte.MaxValue, (byte)158, (byte)161, byte.MaxValue), new Color32((byte)240, (byte)105, (byte)71, byte.MaxValue), new Color32((byte)63, (byte)42, (byte)49, byte.MaxValue) }), new Design("wallflower", "Huntress - Wallflower", (Color32[])(object)new Color32[4] { new Color32((byte)244, (byte)146, (byte)54, byte.MaxValue), new Color32((byte)37, (byte)181, (byte)174, byte.MaxValue), new Color32((byte)239, (byte)211, (byte)171, byte.MaxValue), new Color32((byte)63, (byte)46, (byte)32, byte.MaxValue) }), new Design("shell-shock", "Huntress - Shell Shock", (Color32[])(object)new Color32[4] { new Color32((byte)244, (byte)113, (byte)85, byte.MaxValue), new Color32(byte.MaxValue, (byte)166, (byte)124, byte.MaxValue), new Color32((byte)245, (byte)213, (byte)177, byte.MaxValue), new Color32((byte)123, (byte)46, (byte)37, byte.MaxValue) }), new Design("hot-pursuit", "Huntress - Hot Pursuit", (Color32[])(object)new Color32[4] { new Color32((byte)239, (byte)47, (byte)24, byte.MaxValue), new Color32((byte)249, (byte)70, (byte)35, byte.MaxValue), new Color32((byte)107, (byte)154, (byte)26, byte.MaxValue), new Color32((byte)106, (byte)28, (byte)41, byte.MaxValue) }), new Design("loose-ends", "Huntress - Loose Ends", (Color32[])(object)new Color32[4] { new Color32((byte)157, (byte)46, (byte)67, byte.MaxValue), new Color32((byte)199, (byte)67, (byte)87, byte.MaxValue), new Color32((byte)238, (byte)220, (byte)186, byte.MaxValue), new Color32((byte)81, (byte)21, (byte)37, byte.MaxValue) }), new Design("dawnstrider", "Huntress - Dawnstrider", (Color32[])(object)new Color32[4] { new Color32((byte)234, (byte)227, (byte)205, byte.MaxValue), new Color32((byte)222, (byte)79, (byte)70, byte.MaxValue), new Color32((byte)13, (byte)135, (byte)144, byte.MaxValue), new Color32((byte)19, (byte)213, (byte)239, byte.MaxValue) }) }; private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EclipseHuntressNewSkins)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } [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)("ECLIPSE_HUNTRESS_REWORK_REGISTRATION_FAILED: " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private IEnumerator RegisterAsync() { List<SkinRecord> installed = SkinDiscovery.Load("huntress", delegate(string m) { ((BaseUnityPlugin)this).Logger.LogWarning((object)m); }); if (installed.Count == 0) { yield break; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"ECLIPSE_HUNTRESS_REWORK_REGISTRATION_BEGIN async loader 0.2.0"); GameObject val = BodyCatalog.FindBodyPrefab("HuntressBody"); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("HuntressBody is missing."); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); 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("Huntress's base skin parameters are unavailable."); } SkinnedMeshRenderer[] renderers = modelPrefab.GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.First((SkinnedMeshRenderer r) => ((Object)r).name == "HuntressMesh" && r.bones.Length == 69 && r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "head")); HuntressMaterialProbe.Attach(target); rendererIndex = Array.IndexOf(renderers, 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 Huntress bind pose does not match the renderer."); } RendererInfo originalInfo = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = originalInfo.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && 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; } val3 = load3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Huntress's game shader is unavailable."); } AsyncOperationHandle<Shader> shaderLoad = Addressables.LoadAssetAsync<Shader>((object)"RoR2/Base/Shaders/HGStandard.shader"); retainedAssets.Add(AsyncOperationHandle<Shader>.op_Implicit(shaderLoad)); while (!shaderLoad.IsDone) { CheckLoadDeadline("HGStandard shader"); yield return null; } if ((int)shaderLoad.Status != 1 || !Object.op_Implicit((Object)(object)shaderLoad.Result)) { throw new InvalidOperationException("ECLIPSE_HUNTRESS_SHADER_LOAD_FAILED HGStandard"); } Shader result = shaderLoad.Result; List<SkinDef> list = new List<SkinDef>(); foreach (Design design in Designs.Where((Design d) => installed.Any((SkinRecord r) => r.key == "huntress-" + d.Slug))) { if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipseHuntressNewSkins_" + design.Slug)) { continue; } try { string assetRoot = installed.Single((SkinRecord r) => r.key == "huntress-" + design.Slug).AssetRoot; mesh = ReadMesh(Path.Combine(assetRoot, "model.meshbin"), target, referenceMesh); ((Object)mesh).name = "EclipseHuntressNewSkins_" + design.Slug; material = new Material(result) { name = "matEclipseHuntressNewSkins_" + design.Slug }; material.SetTexture("_MainTex", (Texture)(object)ReadTexture(Path.Combine(assetRoot, "albedo-spec.png"), linear: false)); material.SetTexture("_NormalTex", (Texture)(object)ReadTexture(Path.Combine(assetRoot, "normal.png"), linear: true)); if (!material.HasProperty("_MainTex") || !Object.op_Implicit((Object)(object)material.GetTexture("_MainTex"))) { throw new InvalidOperationException("ECLIPSE_HUNTRESS_ALBEDO_BINDING_FAILED " + design.Slug); } material.SetTextureScale("_MainTex", Vector2.one); material.SetTextureOffset("_MainTex", Vector2.zero); material.SetColor("_EmColor", Color.white); material.SetFloat("_Cull", 2f); material.SetFloat("_ZWrite", 1f); material.SetFloat("_DitherOn", 1f); material.EnableKeyword("DITHER"); material.SetColor("_Color", Color.white); material.SetFloat("_NormalStrength", 0f); material.SetFloat("_Smoothness", 0.15f); material.SetFloat("_SpecularStrength", 0.2f); material.SetFloat("_SpecularExponent", 4f); material.SetFloat("_EmPower", 1f); material.SetTexture("_EmTex", (Texture)(object)ReadTexture(Path.Combine(assetRoot, "emission.png"), linear: false)); material.DisableKeyword("LIMBREMOVAL"); material.SetFloat("_LimbRemovalOn", 0f); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_HUNTRESS_MATERIAL_READY skin=" + design.Slug + " shader=" + ((Object)material.shader).name + " albedo=" + ((Object)material.GetTexture("_MainTex")).name)); RendererInfo val4 = originalInfo; val4.defaultMaterial = material; val4.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val5 = ScriptableObject.CreateInstance<SkinDefParams>(); val5.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val4 }; List<MeshReplacement> list2 = new List<MeshReplacement> { new MeshReplacement { renderer = (Renderer)(object)target, mesh = mesh, meshAddress = new AssetReferenceT<Mesh>("") } }; foreach (SkinnedMeshRenderer item in renderers.Where((SkinnedMeshRenderer r) => ((Object)r).name == "BowMesh" || ((Object)r).name == "HuntressScarfMesh")) { Mesh val6 = new Mesh { name = "EclipseHuntressNewSkins_hidden_" + ((Object)item).name }; val6.vertices = (Vector3[])(object)new Vector3[0]; val6.triangles = new int[0]; list2.Add(new MeshReplacement { renderer = (Renderer)(object)item, mesh = val6, meshAddress = new AssetReferenceT<Mesh>("") }); } val5.meshReplacements = list2.ToArray(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipseHuntressNewSkins_" + design.Slug; skin.nameToken = "ECLIPSE_HUNTRESS_REWORK_" + design.Slug.ToUpperInvariant().Replace('-', '_'); 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 = val5; list.Add(skin); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_HUNTRESS_REWORK_PREPARED name=" + design.Name + " vertices=" + mesh.vertexCount + " triangles=" + mesh.triangles.Length / 3 + " unlocked=true")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("RODANIUS_HUNTRESS_SKIN_FAILED slug=" + design.Slug + " " + ex)); } } if (list.Count != 0) { controller.skins = controller.skins.Concat(list).ToArray(); AttachBoundsDriver(target); registered = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_HUNTRESS_REWORK_REGISTERED count=" + list.Count + " version=0.2.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 == "HuntressBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (!Object.op_Implicit((Object)(object)componentInChildren)) { return; } HuntressMaterialProbe.Attach(((IEnumerable<SkinnedMeshRenderer>)((Component)(object)componentInChildren).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "HuntressMesh"))); ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); SkinDef[] bodySkins = modelPrefab.GetComponent<ModelSkinController>().skins; SkinDef[] second = (val2.skins ?? Array.Empty<SkinDef>()).Where((SkinDef s) => Object.op_Implicit((Object)(object)s) && !bodySkins.Any((SkinDef b) => (Object)(object)b == (Object)(object)s || (Object.op_Implicit((Object)(object)b) && ((Object)b).name == ((Object)s).name))).ToArray(); val2.skins = bodySkins.Concat(second).ToArray(); SkinnedMeshRenderer val3 = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)componentInChildren).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "HuntressMesh")); if (Object.op_Implicit((Object)(object)val3)) { AttachBoundsDriver(val3); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ECLIPSE_HUNTRESS_REWORK_DISPLAY_READY skins=" + val2.skins.Length)); } private static void AttachBoundsDriver(SkinnedMeshRenderer target) { if (!Object.op_Implicit((Object)(object)((Component)target).GetComponent<NewHuntressSkinBounds>())) { ((Component)target).gameObject.AddComponent<NewHuntressSkinBounds>(); } } 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_0363: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0397: 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_03a5: 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)) != "HEP1") { 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 != 69) { 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 = "EclipseHuntressAuthoredMesh", indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } 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; } } public sealed class NewHuntressSkinBounds : MonoBehaviour { private SkinnedMeshRenderer target; private Bounds original; private bool applied; private Mesh boundedMesh; private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) target = ((Component)this).GetComponent<SkinnedMeshRenderer>(); if (Object.op_Implicit((Object)(object)target)) { original = ((Renderer)target).localBounds; } } private void LateUpdate() { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)target)) { return; } bool flag = Object.op_Implicit((Object)(object)target.sharedMesh) && ((Object)target.sharedMesh).name.StartsWith("EclipseHuntressNewSkins_", StringComparison.Ordinal); if (flag && (!applied || (Object)(object)boundedMesh != (Object)(object)target.sharedMesh)) { if (!applied) { original = ((Renderer)target).localBounds; } Bounds localBounds = default(Bounds); ((Bounds)(ref localBounds))..ctor(new Vector3(0f, 0f, 0.3f), new Vector3(6.5f, 6.5f, 6.5f)); ((Bounds)(ref localBounds)).Encapsulate(target.sharedMesh.bounds); ((Renderer)target).localBounds = localBounds; applied = true; boundedMesh = target.sharedMesh; } else if (!flag && applied) { ((Renderer)target).localBounds = original; applied = false; boundedMesh = null; } } private void OnDisable() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)target) && applied) { ((Renderer)target).localBounds = original; } applied = false; boundedMesh = null; } } } namespace Rodanius.Standalone { public static class CatalogueSpecs { public static bool Matches(SkinRecord r) { switch (r.key) { case "acrid-bog-hopper": if (r.skinId == "EclipsePlaytestAcridE1BogHopper" && r.family == "single" && r.name == "Bog Hopper" && r.survivor == "Acrid") { return r.tier == 1; } return false; case "acrid-duck-and-cover": if (r.skinId == "EclipsePlaytestAcridE2DuckAndCover" && r.family == "single" && r.name == "Duck and Cover" && r.survivor == "Acrid") { return r.tier == 2; } return false; case "acrid-trash-panda": if (r.skinId == "EclipsePlaytestAcridE3TrashPanda" && r.family == "single" && r.name == "Trash Panda" && r.survivor == "Acrid") { return r.tier == 3; } return false; case "acrid-good-boy": if (r.skinId == "EclipsePlaytestAcridE4GoodBoy" && r.family == "single" && r.name == "Good Boy" && r.survivor == "Acrid") { return r.tier == 4; } return false; case "acrid-ginger-cat": if (r.skinId == "EclipsePlaytestAcridE5GingerCat" && r.family == "single" && r.name == "Ginger Cat" && r.survivor == "Acrid") { return r.tier == 5; } return false; case "acrid-squirrel": if (r.skinId == "EclipsePlaytestAcridE6Squirrel" && r.family == "single" && r.name == "Squirrel" && r.survivor == "Acrid") { return r.tier == 6; } return false; case "acrid-goat": if (r.skinId == "EclipsePlaytestAcridE7Goat" && r.family == "single" && r.name == "Goat" && r.survivor == "Acrid") { return r.tier == 7; } return false; case "acrid-abyssal-angler": if (r.skinId == "EclipsePlaytestAcridE8AbyssalAngler" && r.family == "single" && r.name == "Abyssal Angler" && r.survivor == "Acrid") { return r.tier == 8; } return false; case "bandit-corner-crew": if (r.skinId == "skinEclipsePlaytestBanditE1" && r.family == "single" && r.name == "Corner Crew" && r.survivor == "Bandit") { return r.tier == 1; } return false; case "bandit-after-hours": if (r.skinId == "skinEclipsePlaytestBanditE2" && r.family == "single" && r.name == "After Hours" && r.survivor == "Bandit") { return r.tier == 2; } return false; case "bandit-house-always-wins": if (r.skinId == "skinEclipsePlaytestBanditE3" && r.family == "single" && r.name == "House Always Wins" && r.survivor == "Bandit") { return r.tier == 3; } return false; case "bandit-card-shark": if (r.skinId == "skinEclipsePlaytestBanditE5" && r.family == "single" && r.name == "Card Shark" && r.survivor == "Bandit") { return r.tier == 5; } return false; case "chef-crab-rangoon": if (r.skinId == "EclipsePlaytestChefE2CrabRangoon" && r.family == "single" && r.name == "Crab Rangoon" && r.survivor == "CHEF") { return r.tier == 1; } return false; case "commando-frontier-recruit": if (r.skinId == "skinEclipsePlaytestCommandoE1" && r.family == "single" && r.name == "Frontier Recruit" && r.survivor == "Commando") { return r.tier == 1; } return false; case "commando-vacuum-breacher": if (r.skinId == "skinEclipsePlaytestCommandoE2" && r.family == "single" && r.name == "Vacuum Breacher" && r.survivor == "Commando") { return r.tier == 2; } return false; case "commando-expedition-marshal": if (r.skinId == "skinEclipsePlaytestCommandoE3" && r.family == "single" && r.name == "Expedition Marshal" && r.survivor == "Commando") { return r.tier == 3; } return false; case "commando-clockwork-infantry": if (r.skinId == "skinEclipsePlaytestCommandoE4" && r.family == "single" && r.name == "Clockwork Infantry" && r.survivor == "Commando") { return r.tier == 4; } return false; case "commando-action-figure": if (r.skinId == "skinEclipsePlaytestCommandoE5" && r.family == "single" && r.name == "Action Figure" && r.survivor == "Commando") { return r.tier == 5; } return false; case "commando-quartermaster": if (r.skinId == "skinEclipsePlaytestCommandoE6" && r.family == "single" && r.name == "Quartermaster" && r.survivor == "Commando") { return r.tier == 6; } return false; case "commando-one-man-band": if (r.skinId == "skinEclipsePlaytestCommandoE7" && r.family == "single" && r.name == "One-Man Band" && r.survivor == "Commando") { return r.tier == 7; } return false; case "commando-extinction-protocol": if (r.skinId == "skinEclipsePlaytestCommandoE8" && r.family == "single" && r.name == "Extinction Protocol" && r.survivor == "Commando") { return r.tier == 8; } return false; case "drifter-happy-camper": if (r.skinId == "EclipsePlaytestDrifterE1HappyCamper" && r.family == "single" && r.name == "Happy Camper" && r.survivor == "Drifter") { return r.tier == 1; } return false; case "engineer-union-builder": if (r.skinId == "skinEclipsePlaytestEngineerE1_union-builder" && r.family == "single" && r.name == "Union Builder" && r.survivor == "Engineer") { return r.tier == 1; } return false; case "engineer-mine-surveyor": if (r.skinId == "skinEclipsePlaytestEngineerE2_mine-surveyor" && r.family == "single" && r.name == "Mine Surveyor" && r.survivor == "Engineer") { return r.tier == 2; } return false; case "false-son-penguin": if (r.skinId == "EclipsePlaytestFalseSonE3Penguin" && r.family == "single" && r.name == "Penguin" && r.survivor == "False Son") { return r.tier == 1; } return false; case "huntress-hare-trigger": if (r.skinId == "skinEclipseHuntressNewSkins_hare-trigger" && r.family == "huntress" && r.name == "Hare Trigger" && r.survivor == "Huntress") { return r.tier == 1; } return false; case "huntress-pink-slip": if (r.skinId == "skinEclipseHuntressNewSkins_pink-slip" && r.family == "huntress" && r.name == "Pink Slip" && r.survivor == "Huntress") { return r.tier == 2; } return false; case "huntress-wallflower": if (r.skinId == "skinEclipseHuntressNewSkins_wallflower" && r.family == "huntress" && r.name == "Wallflower" && r.survivor == "Huntress") { return r.tier == 3; } return false; case "huntress-shell-shock": if (r.skinId == "skinEclipseHuntressNewSkins_shell-shock" && r.family == "huntress" && r.name == "Shell Shock" && r.survivor == "Huntress") { return r.tier == 4; } return false; case "huntress-hot-pursuit": if (r.skinId == "skinEclipseHuntressNewSkins_hot-pursuit" && r.family == "huntress" && r.name == "Hot Pursuit" && r.survivor == "Huntress") { return r.tier == 5; } return false; case "huntress-banana": if (r.skinId == "skinHuntressLiquidAssetsPlaytest_liquid-assets" && r.family == "single" && r.name == "Banana" && r.survivor == "Huntress") { return r.tier == 6; } return false; case "huntress-loose-ends": if (r.skinId == "skinEclipseHuntressNewSkins_loose-ends" && r.family == "huntress" && r.name == "Loose Ends" && r.survivor == "Huntress") { return r.tier == 7; } return false; case "huntress-dawnstrider": if (r.skinId == "skinEclipseHuntressNewSkins_dawnstrider" && r.family == "huntress" && r.name == "Dawnstrider" && r.survivor == "Huntress") { return r.tier == 8; } return false; case "loader-go-fetch": if (r.skinId == "EclipseLoaderE1" && r.family == "loader" && r.name == "Go Fetch" && r.survivor == "Loader") { return r.tier == 1; } return false; case "loader-bear-knuckle": if (r.skinId == "EclipseLoaderE2" && r.family == "loader" && r.name == "Bear Knuckle" && r.survivor == "Loader") { return r.tier == 2; } return false; case "loader-knuckle-dragger": if (r.skinId == "EclipseLoaderE3" && r.family == "loader" && r.name == "Knuckle Dragger" && r.survivor == "Loader") { return r.tier == 3; } return false; case "loader-brick-house": if (r.skinId == "EclipseLoaderE4" && r.family == "loader" && r.name == "Brick House" && r.survivor == "Loader") { return r.tier == 4; } return false; case "loader-dead-weight": if (r.skinId == "EclipseLoaderE5" && r.family == "loader" && r.name == "Dead Weight" && r.survivor == "Loader") { return r.tier == 5; } return false; case "loader-rubber-bandit": if (r.skinId == "EclipseLoaderE6" && r.family == "loader" && r.name == "Rubber Bandit" && r.survivor == "Loader") { return r.tier == 6; } return false; case "loader-high-five": if (r.skinId == "EclipseLoaderE7" && r.family == "loader" && r.name == "High Five" && r.survivor == "Loader") { return r.tier == 7; } return false; case "loader-titan-champion": if (r.skinId == "EclipseLoaderE8" && r.family == "loader" && r.name == "Titan Champion" && r.survivor == "Loader") { return r.tier == 8; } return false; case "mul-t-yard-salvager": if (r.skinId == "skinEclipsePlaytest_MULT_E1" && r.family == "single" && r.name == "Yard Salvager" && r.survivor == "MUL-T") { return r.tier == 1; } return false; case "mul-t-timber-hauler": if (r.skinId == "skinEclipsePlaytest_MULT_E2" && r.family == "single" && r.name == "Timber Hauler" && r.survivor == "MUL-T") { return r.tier == 2; } return false; case "mul-t-deep-salvage-unit": if (r.skinId == "skinEclipsePlaytest_MULT_E3" && r.family == "single" && r.name == "Deep-Salvage Unit" && r.survivor == "MUL-T") { return r.tier == 3; } return false; case "mercenary-roadworn-ronin": if (r.skinId == "EclipsePlaytestMercenaryE1RoadwornRonin" && r.family == "single" && r.name == "Roadworn Ronin" && r.survivor == "Mercenary") { return r.tier == 1; } return false; case "mercenary-canopy-cutter": if (r.skinId == "EclipsePlaytestMercenaryE3CanopyCutter" && r.family == "single" && r.name == "Canopy Cutter" && r.survivor == "Mercenary") { return r.tier == 3; } return false; case "mercenary-circuit-duelist": if (r.skinId == "EclipsePlaytestMercenaryE2CircuitDuelist" && r.family == "single" && r.name == "Circuit Duelist" && r.survivor == "Mercenary") { return r.tier == 2; } return false; case "mercenary-deli-duelist": if (r.skinId == "EclipsePlaytestMercenaryE7DeliDuelist" && r.family == "single" && r.name == "Deli Duelist" && r.survivor == "Mercenary") { return r.tier == 7; } return false; case "rex-prickly-customer": if (r.skinId == "skinEclipseRexPricklyCustomer" && r.family == "single" && r.name == "Prickly Customer" && r.survivor == "REX") { return r.tier == 1; } return false; case "railgunner-hole-in-one": if (r.skinId == "EclipseRailgunnerE1" && r.family == "railgunner" && r.name == "Hole in One" && r.survivor == "Railgunner") { return r.tier == 1; } return false; case "railgunner-night-sight": if (r.skinId == "EclipseRailgunnerE2" && r.family == "railgunner" && r.name == "Night Sight" && r.survivor == "Railgunner") { return r.tier == 2; } return false; case "railgunner-ring-leader": if (r.skinId == "EclipseRailgunnerE3" && r.family == "railgunner" && r.name == "Ring Leader" && r.survivor == "Railgunner") { return r.tier == 3; } return false; case "railgunner-fire-away": if (r.skinId == "EclipseRailgunnerE4" && r.family == "railgunner" && r.name == "Fire Away" && r.survivor == "Railgunner") { return r.tier == 4; } return false; case "railgunner-point-taken": if (r.skinId == "EclipseRailgunnerE5" && r.family == "railgunner" && r.name == "Point Taken" && r.survivor == "Railgunner") { return r.tier == 5; } return false; case "railgunner-express-delivery": if (r.skinId == "EclipseRailgunnerE6" && r.family == "railgunner" && r.name == "Express Delivery" && r.survivor == "Railgunner") { return r.tier == 6; } return false; case "railgunner-last-straw": if (r.skinId == "EclipseRailgunnerE7" && r.family == "railgunner" && r.name == "Last Straw" && r.survivor == "Railgunner") { return r.tier == 7; } return false; case "railgunner-horizon-lancer": if (r.skinId == "EclipseRailgunnerE8" && r.family == "railgunner" && r.name == "Horizon Lancer" && r.survivor == "Railgunner") { return r.tier == 8; } return false; case "seeker-breaditation": if (r.skinId == "EclipsePlaytestSeekerE7Breaditation" && r.family == "single" && r.name == "Breaditation" && r.survivor == "Seeker") { return r.tier == 1; } return false; case "void-fiend-desert-castaway": if (r.skinId == "skinEclipsePlaytestVoidFiendE1" && r.family == "single" && r.name == "Desert Castaway" && r.survivor == "Void Fiend") { return r.tier == 1; } return false; case "void-fiend-live-wire": if (r.skinId == "skinEclipsePlaytestVoidFiendE2" && r.family == "single" && r.name == "Live Wire" && r.survivor == "Void Fiend") { return r.tier == 2; } return false; case "void-fiend-pressure-guest": if (r.skinId == "skinEclipsePlaytestVoidFiendE3" && r.family == "single" && r.name == "Pressure Guest" && r.survivor == "Void Fiend") { return r.tier == 3; } return false; case "void-fiend-orange-you-glad": if (r.skinId == "skinEclipsePlaytestVoidFiendE4" && r.family == "single" && r.name == "Orange You Glad" && r.survivor == "Void Fiend") { return r.tier == 4; } return false; case "void-fiend-burnt-offering": if (r.skinId == "skinEclipsePlaytestVoidFiendE5" && r.family == "single" && r.name == "Burnt Offering" && r.survivor == "Void Fiend") { return r.tier == 5; } return false; case "void-fiend-public-information": if (r.skinId == "skinEclipsePlaytestVoidFiendE6" && r.family == "single" && r.name == "Public Information" && r.survivor == "Void Fiend") { return r.tier == 6; } return false; case "void-fiend-surprise-inside": if (r.skinId == "skinEclipsePlaytestVoidFiendE7" && r.family == "single" && r.name == "Surprise Inside" && r.survivor == "Void Fiend") { return r.tier == 7; } return false; case "void-fiend-containment-impossible": if (r.skinId == "skinEclipsePlaytestVoidFiendE8" && r.family == "single" && r.name == "Containment Impossible" && r.survivor == "Void Fiend") { return r.tier == 8; } return false; default: return false; } } } [Serializable] public sealed class AssetFile { public string path; public string sha256; } [Serializable] public sealed class SkinRecord { public int schema; public int tier; public string key; public string name; public string survivor; public string family; public string skinId; public string assetDirectory; public string icon; public string iconSha256; public AssetFile[] files; [NonSerialized] public string Root; public string AssetRoot => SkinDiscovery.SafePath(Root, assetDirectory); } public static class SkinDiscovery { public static string SafePath(string root, string relative) { if (string.IsNullOrEmpty(relative) || Path.IsPathRooted(relative) || relative.Split('/', '\\').Any((string x) => x == ".." || x == "")) { throw new InvalidDataException("Invalid package-relative path"); } string text = Path.GetFullPath(root).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; string fullPath = Path.GetFullPath(Path.Combine(root, relative)); if (!fullPath.StartsWith(text, StringComparison.OrdinalIgnoreCase) && fullPath != text.TrimEnd(Path.DirectorySeparatorChar)) { throw new InvalidDataException("Package path escaped root"); } return fullPath; } private static IEnumerable<string> FindRecords(string root, Action<string> log) { Stack<string> todo = new Stack<string>(); todo.Push(root); while (todo.Count > 0) { string dir = todo.Pop(); string text = Path.Combine(dir, "rodanius-skin.json"); if (File.Exists(text)) { yield return text; } string[] directories; try { directories = Directory.GetDirectories(dir); } catch (Exception ex) { log("RODANIUS_DISCOVERY_SKIPPED " + dir + " " + ex.Message); continue; } string[] array = directories; foreach (string text2 in array) { try { if ((File.GetAttributes(text2) & FileAttributes.ReparsePoint) == 0) { todo.Push(text2); } } catch (Exception ex2) { log("RODANIUS_DISCOVERY_SKIPPED " + ex2.Message); } } } } public static string Hash(string path) { using FileStream inputStream = File.OpenRead(path); using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant(); } public static List<SkinRecord> Load(string family, Action<string> log, bool verifyAssets = true) { List<SkinRecord> list = new List<SkinRecord>(); foreach (string item in FindRecords(Paths.PluginPath, log)) { try { if (new FileInfo(item).Length > 262144) { throw new InvalidDataException("Manifest too large"); } SkinRecord skinRecord = JsonUtility.FromJson<SkinRecord>(File.ReadAllText(item)); if (skinRecord == null || skinRecord.schema != 1 || !CatalogueSpecs.Matches(skinRecord)) { throw new InvalidDataException("Unknown standalone skin identity"); } if (family != null && skinRecord.family != family) { continue; } skinRecord.Root = Path.GetDirectoryName(item); SafePath(skinRecord.Root, skinRecord.assetDirectory); SafePath(skinRecord.Root, skinRecord.icon); if (verifyAssets) { if (skinRecord.files == null || skinRecord.files.Length == 0 || skinRecord.files.Length > 100) { throw new InvalidDataException("Asset inventory missing"); } AssetFile[] files = skinRecord.files; foreach (AssetFile assetFile in files) { if (assetFile == null || assetFile.sha256 == null || assetFile.sha256.Length != 64 || Hash(SafePath(skinRecord.Root, assetFile.path)) != assetFile.sha256) { throw new InvalidDataException("Asset hash mismatch: " + ((assetFile == null) ? "null" : assetFile.path)); } } } list.Add(skinRecord); } catch (Exception ex) { log("RODANIUS_SKIN_PACKAGE_REJECTED file=" + item + " error=" + ex.Message); } } List<SkinRecord> list2 = new List<SkinRecord>(); foreach (IGrouping<string, SkinRecord> item2 in list.GroupBy<SkinRecord, string>((SkinRecord r) => r.skinId, StringComparer.Ordinal)) { if (item2.Count() != 1) { log("RODANIUS_DUPLICATE_SKIN_PACKAGE id=" + item2.Key + " paths=" + string.Join(";", item2.Select((SkinRecord r) => r.Root))); } else { list2.Add(item2.Single()); } } return list2.OrderBy<SkinRecord, string>((SkinRecord r) => r.survivor, StringComparer.Ordinal).ThenBy((SkinRecord r) => r.tier).ToList(); } } }
BepInEx/plugins/RodaniusSkinRuntime/Rodanius.SkinPresentation.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using BepInEx; using HG.Reflection; using R2API; using RoR2; using RoR2.UI.MainMenu; using Rodanius.Standalone; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace Rodanius.SkinPresentation { [BepInPlugin("rodanius.skinpresentation", "Rodanius Skin Presentation", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Presentation : BaseUnityPlugin { private static Presentation instance; private readonly Dictionary<string, Sprite> portraits = new Dictionary<string, Sprite>(StringComparer.Ordinal); private readonly Dictionary<string, string> names = new Dictionary<string, string>(StringComparer.Ordinal); private readonly HashSet<string> reported = new HashSet<string>(StringComparer.Ordinal); private readonly HashSet<string> missing = new HashSet<string>(StringComparer.Ordinal); private bool loaded; private void Awake() { instance = this; RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Apply)); MainMenuController.OnMainMenuInitialised += Apply; ((BaseUnityPlugin)this).Logger.LogInfo((object)("RODANIUS_PRESENTATION_LOCATION " + ((BaseUnityPlugin)this).Info.Location)); } [SystemInitializer(new Type[] { typeof(SkinCatalog) })] private static void Initialize() { if (Object.op_Implicit((Object)(object)instance)) { instance.Apply(); } } private void Load() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) if (loaded) { return; } loaded = true; foreach (SkinRecord item in SkinDiscovery.Load(null, delegate(string s) { ((BaseUnityPlugin)this).Logger.LogWarning((object)s); }, verifyAssets: false)) { try { ((BaseUnityPlugin)this).Logger.LogInfo((object)("RODANIUS_SKIN_PACKAGE_FOUND id=" + item.skinId + " path=" + item.Root)); string text = SkinDiscovery.SafePath(item.Root, item.icon); if (new FileInfo(text).Length > 4194304 || item.iconSha256 == null || SkinDiscovery.Hash(text) != item.iconSha256) { throw new InvalidDataException("Portrait hash/size mismatch"); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = "Rodanius_" + item.key, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; try { if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text), false) || ((Texture)val).width != 256 || ((Texture)val).height != 256) { throw new InvalidDataException("Expected 256px portrait"); } portraits.Add(item.skinId, Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f))); names.Add(item.skinId, item.name); } catch { Object.Destroy((Object)(object)val); throw; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("RODANIUS_PORTRAIT_REJECTED key=" + item.key + " error=" + ex.Message)); } } } private void Apply() { try { Load(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < SkinCatalog.skinCount; i++) { SkinDef skinDef = SkinCatalog.GetSkinDef((SkinIndex)i); if (Object.op_Implicit((Object)(object)skinDef) && portraits.TryGetValue(((Object)skinDef).name, out var value)) { hashSet.Add(((Object)skinDef).name); skinDef.icon = value; if (reported.Add(((Object)skinDef).name)) { LanguageAPI.Add(skinDef.nameToken, names[((Object)skinDef).name]); ((BaseUnityPlugin)this).Logger.LogInfo((object)("RODANIUS_PORTRAIT_APPLIED " + ((Object)skinDef).name)); } } } foreach (string key in portraits.Keys) { if (!hashSet.Contains(key) && missing.Add(key)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("RODANIUS_SKIN_NOT_REGISTERED id=" + key + " packagePresent=true; inspect this skin's registration error and duplicate plugin locations.")); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("RODANIUS_PORTRAIT_UPDATE_FAILED " + ex)); } } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(Apply)); MainMenuController.OnMainMenuInitialised -= Apply; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } } namespace Rodanius.Standalone { public static class CatalogueSpecs { public static bool Matches(SkinRecord r) { switch (r.key) { case "acrid-bog-hopper": if (r.skinId == "EclipsePlaytestAcridE1BogHopper" && r.family == "single" && r.name == "Bog Hopper" && r.survivor == "Acrid") { return r.tier == 1; } return false; case "acrid-duck-and-cover": if (r.skinId == "EclipsePlaytestAcridE2DuckAndCover" && r.family == "single" && r.name == "Duck and Cover" && r.survivor == "Acrid") { return r.tier == 2; } return false; case "acrid-trash-panda": if (r.skinId == "EclipsePlaytestAcridE3TrashPanda" && r.family == "single" && r.name == "Trash Panda" && r.survivor == "Acrid") { return r.tier == 3; } return false; case "acrid-good-boy": if (r.skinId == "EclipsePlaytestAcridE4GoodBoy" && r.family == "single" && r.name == "Good Boy" && r.survivor == "Acrid") { return r.tier == 4; } return false; case "acrid-ginger-cat": if (r.skinId == "EclipsePlaytestAcridE5GingerCat" && r.family == "single" && r.name == "Ginger Cat" && r.survivor == "Acrid") { return r.tier == 5; } return false; case "acrid-squirrel": if (r.skinId == "EclipsePlaytestAcridE6Squirrel" && r.family == "single" && r.name == "Squirrel" && r.survivor == "Acrid") { return r.tier == 6; } return false; case "acrid-goat": if (r.skinId == "EclipsePlaytestAcridE7Goat" && r.family == "single" && r.name == "Goat" && r.survivor == "Acrid") { return r.tier == 7; } return false; case "acrid-abyssal-angler": if (r.skinId == "EclipsePlaytestAcridE8AbyssalAngler" && r.family == "single" && r.name == "Abyssal Angler" && r.survivor == "Acrid") { return r.tier == 8; } return false; case "bandit-corner-crew": if (r.skinId == "skinEclipsePlaytestBanditE1" && r.family == "single" && r.name == "Corner Crew" && r.survivor == "Bandit") { return r.tier == 1; } return false; case "bandit-after-hours": if (r.skinId == "skinEclipsePlaytestBanditE2" && r.family == "single" && r.name == "After Hours" && r.survivor == "Bandit") { return r.tier == 2; } return false; case "bandit-house-always-wins": if (r.skinId == "skinEclipsePlaytestBanditE3" && r.family == "single" && r.name == "House Always Wins" && r.survivor == "Bandit") { return r.tier == 3; } return false; case "bandit-card-shark": if (r.skinId == "skinEclipsePlaytestBanditE5" && r.family == "single" && r.name == "Card Shark" && r.survivor == "Bandit") { return r.tier == 5; } return false; case "chef-crab-rangoon": if (r.skinId == "EclipsePlaytestChefE2CrabRangoon" && r.family == "single" && r.name == "Crab Rangoon" && r.survivor == "CHEF") { return r.tier == 1; } return false; case "commando-frontier-recruit": if (r.skinId == "skinEclipsePlaytestCommandoE1" && r.family == "single" && r.name == "Frontier Recruit" && r.survivor == "Commando") { return r.tier == 1; } return false; case "commando-vacuum-breacher": if (r.skinId == "skinEclipsePlaytestCommandoE2" && r.family == "single" && r.name == "Vacuum Breacher" && r.survivor == "Commando") { return r.tier == 2; } return false; case "commando-expedition-marshal": if (r.skinId == "skinEclipsePlaytestCommandoE3" && r.family == "single" && r.name == "Expedition Marshal" && r.survivor == "Commando") { return r.tier == 3; } return false; case "commando-clockwork-infantry": if (r.skinId == "skinEclipsePlaytestCommandoE4" && r.family == "single" && r.name == "Clockwork Infantry" && r.survivor == "Commando") { return r.tier == 4; } return false; case "commando-action-figure": if (r.skinId == "skinEclipsePlaytestCommandoE5" && r.family == "single" && r.name == "Action Figure" && r.survivor == "Commando") { return r.tier == 5; } return false; case "commando-quartermaster": if (r.skinId == "skinEclipsePlaytestCommandoE6" && r.family == "single" && r.name == "Quartermaster" && r.survivor == "Commando") { return r.tier == 6; } return false; case "commando-one-man-band": if (r.skinId == "skinEclipsePlaytestCommandoE7" && r.family == "single" && r.name == "One-Man Band" && r.survivor == "Commando") { return r.tier == 7; } return false; case "commando-extinction-protocol": if (r.skinId == "skinEclipsePlaytestCommandoE8" && r.family == "single" && r.name == "Extinction Protocol" && r.survivor == "Commando") { return r.tier == 8; } return false; case "drifter-happy-camper": if (r.skinId == "EclipsePlaytestDrifterE1HappyCamper" && r.family == "single" && r.name == "Happy Camper" && r.survivor == "Drifter") { return r.tier == 1; } return false; case "engineer-union-builder": if (r.skinId == "skinEclipsePlaytestEngineerE1_union-builder" && r.family == "single" && r.name == "Union Builder" && r.survivor == "Engineer") { return r.tier == 1; } return false; case "engineer-mine-surveyor": if (r.skinId == "skinEclipsePlaytestEngineerE2_mine-surveyor" && r.family == "single" && r.name == "Mine Surveyor" && r.survivor == "Engineer") { return r.tier == 2; } return false; case "false-son-penguin": if (r.skinId == "EclipsePlaytestFalseSonE3Penguin" && r.family == "single" && r.name == "Penguin" && r.survivor == "False Son") { return r.tier == 1; } return false; case "huntress-hare-trigger": if (r.skinId == "skinEclipseHuntressNewSkins_hare-trigger" && r.family == "huntress" && r.name == "Hare Trigger" && r.survivor == "Huntress") { return r.tier == 1; } return false; case "huntress-pink-slip": if (r.skinId == "skinEclipseHuntressNewSkins_pink-slip" && r.family == "huntress" && r.name == "Pink Slip" && r.survivor == "Huntress") { return r.tier == 2; } return false; case "huntress-wallflower": if (r.skinId == "skinEclipseHuntressNewSkins_wallflower" && r.family == "huntress" && r.name == "Wallflower" && r.survivor == "Huntress") { return r.tier == 3; } return false; case "huntress-shell-shock": if (r.skinId == "skinEclipseHuntressNewSkins_shell-shock" && r.family == "huntress" && r.name == "Shell Shock" && r.survivor == "Huntress") { return r.tier == 4; } return false; case "huntress-hot-pursuit": if (r.skinId == "skinEclipseHuntressNewSkins_hot-pursuit" && r.family == "huntress" && r.name == "Hot Pursuit" && r.survivor == "Huntress") { return r.tier == 5; } return false; case "huntress-banana": if (r.skinId == "skinHuntressLiquidAssetsPlaytest_liquid-assets" && r.family == "single" && r.name == "Banana" && r.survivor == "Huntress") { return r.tier == 6; } return false; case "huntress-loose-ends": if (r.skinId == "skinEclipseHuntressNewSkins_loose-ends" && r.family == "huntress" && r.name == "Loose Ends" && r.survivor == "Huntress") { return r.tier == 7; } return false; case "huntress-dawnstrider": if (r.skinId == "skinEclipseHuntressNewSkins_dawnstrider" && r.family == "huntress" && r.name == "Dawnstrider" && r.survivor == "Huntress") { return r.tier == 8; } return false; case "loader-go-fetch": if (r.skinId == "EclipseLoaderE1" && r.family == "loader" && r.name == "Go Fetch" && r.survivor == "Loader") { return r.tier == 1; } return false; case "loader-bear-knuckle": if (r.skinId == "EclipseLoaderE2" && r.family == "loader" && r.name == "Bear Knuckle" && r.survivor == "Loader") { return r.tier == 2; } return false; case "loader-knuckle-dragger": if (r.skinId == "EclipseLoaderE3" && r.family == "loader" && r.name == "Knuckle Dragger" && r.survivor == "Loader") { return r.tier == 3; } return false; case "loader-brick-house": if (r.skinId == "EclipseLoaderE4" && r.family == "loader" && r.name == "Brick House" && r.survivor == "Loader") { return r.tier == 4; } return false; case "loader-dead-weight": if (r.skinId == "EclipseLoaderE5" && r.family == "loader" && r.name == "Dead Weight" && r.survivor == "Loader") { return r.tier == 5; } return false; case "loader-rubber-bandit": if (r.skinId == "EclipseLoaderE6" && r.family == "loader" && r.name == "Rubber Bandit" && r.survivor == "Loader") { return r.tier == 6; } return false; case "loader-high-five": if (r.skinId == "EclipseLoaderE7" && r.family == "loader" && r.name == "High Five" && r.survivor == "Loader") { return r.tier == 7; } return false; case "loader-titan-champion": if (r.skinId == "EclipseLoaderE8" && r.family == "loader" && r.name == "Titan Champion" && r.survivor == "Loader") { return r.tier == 8; } return false; case "mul-t-yard-salvager": if (r.skinId == "skinEclipsePlaytest_MULT_E1" && r.family == "single" && r.name == "Yard Salvager" && r.survivor == "MUL-T") { return r.tier == 1; } return false; case "mul-t-timber-hauler": if (r.skinId == "skinEclipsePlaytest_MULT_E2" && r.family == "single" && r.name == "Timber Hauler" && r.survivor == "MUL-T") { return r.tier == 2; } return false; case "mul-t-deep-salvage-unit": if (r.skinId == "skinEclipsePlaytest_MULT_E3" && r.family == "single" && r.name == "Deep-Salvage Unit" && r.survivor == "MUL-T") { return r.tier == 3; } return false; case "mercenary-roadworn-ronin": if (r.skinId == "EclipsePlaytestMercenaryE1RoadwornRonin" && r.family == "single" && r.name == "Roadworn Ronin" && r.survivor == "Mercenary") { return r.tier == 1; } return false; case "mercenary-canopy-cutter": if (r.skinId == "EclipsePlaytestMercenaryE3CanopyCutter" && r.family == "single" && r.name == "Canopy Cutter" && r.survivor == "Mercenary") { return r.tier == 3; } return false; case "mercenary-circuit-duelist": if (r.skinId == "EclipsePlaytestMercenaryE2CircuitDuelist" && r.family == "single" && r.name == "Circuit Duelist" && r.survivor == "Mercenary") { return r.tier == 2; } return false; case "mercenary-deli-duelist": if (r.skinId == "EclipsePlaytestMercenaryE7DeliDuelist" && r.family == "single" && r.name == "Deli Duelist" && r.survivor == "Mercenary") { return r.tier == 7; } return false; case "rex-prickly-customer": if (r.skinId == "skinEclipseRexPricklyCustomer" && r.family == "single" && r.name == "Prickly Customer" && r.survivor == "REX") { return r.tier == 1; } return false; case "railgunner-hole-in-one": if (r.skinId == "EclipseRailgunnerE1" && r.family == "railgunner" && r.name == "Hole in One" && r.survivor == "Railgunner") { return r.tier == 1; } return false; case "railgunner-night-sight": if (r.skinId == "EclipseRailgunnerE2" && r.family == "railgunner" && r.name == "Night Sight" && r.survivor == "Railgunner") { return r.tier == 2; } return false; case "railgunner-ring-leader": if (r.skinId == "EclipseRailgunnerE3" && r.family == "railgunner" && r.name == "Ring Leader" && r.survivor == "Railgunner") { return r.tier == 3; } return false; case "railgunner-fire-away": if (r.skinId == "EclipseRailgunnerE4" && r.family == "railgunner" && r.name == "Fire Away" && r.survivor == "Railgunner") { return r.tier == 4; } return false; case "railgunner-point-taken": if (r.skinId == "EclipseRailgunnerE5" && r.family == "railgunner" && r.name == "Point Taken" && r.survivor == "Railgunner") { return r.tier == 5; } return false; case "railgunner-express-delivery": if (r.skinId == "EclipseRailgunnerE6" && r.family == "railgunner" && r.name == "Express Delivery" && r.survivor == "Railgunner") { return r.tier == 6; } return false; case "railgunner-last-straw": if (r.skinId == "EclipseRailgunnerE7" && r.family == "railgunner" && r.name == "Last Straw" && r.survivor == "Railgunner") { return r.tier == 7; } return false; case "railgunner-horizon-lancer": if (r.skinId == "EclipseRailgunnerE8" && r.family == "railgunner" && r.name == "Horizon Lancer" && r.survivor == "Railgunner") { return r.tier == 8; } return false; case "seeker-breaditation": if (r.skinId == "EclipsePlaytestSeekerE7Breaditation" && r.family == "single" && r.name == "Breaditation" && r.survivor == "Seeker") { return r.tier == 1; } return false; case "void-fiend-desert-castaway": if (r.skinId == "skinEclipsePlaytestVoidFiendE1" && r.family == "single" && r.name == "Desert Castaway" && r.survivor == "Void Fiend") { return r.tier == 1; } return false; case "void-fiend-live-wire": if (r.skinId == "skinEclipsePlaytestVoidFiendE2" && r.family == "single" && r.name == "Live Wire" && r.survivor == "Void Fiend") { return r.tier == 2; } return false; case "void-fiend-pressure-guest": if (r.skinId == "skinEclipsePlaytestVoidFiendE3" && r.family == "single" && r.name == "Pressure Guest" && r.survivor == "Void Fiend") { return r.tier == 3; } return false; case "void-fiend-orange-you-glad": if (r.skinId == "skinEclipsePlaytestVoidFiendE4" && r.family == "single" && r.name == "Orange You Glad" && r.survivor == "Void Fiend") { return r.tier == 4; } return false; case "void-fiend-burnt-offering": if (r.skinId == "skinEclipsePlaytestVoidFiendE5" && r.family == "single" && r.name == "Burnt Offering" && r.survivor == "Void Fiend") { return r.tier == 5; } return false; case "void-fiend-public-information": if (r.skinId == "skinEclipsePlaytestVoidFiendE6" && r.family == "single" && r.name == "Public Information" && r.survivor == "Void Fiend") { return r.tier == 6; } return false; case "void-fiend-surprise-inside": if (r.skinId == "skinEclipsePlaytestVoidFiendE7" && r.family == "single" && r.name == "Surprise Inside" && r.survivor == "Void Fiend") { return r.tier == 7; } return false; case "void-fiend-containment-impossible": if (r.skinId == "skinEclipsePlaytestVoidFiendE8" && r.family == "single" && r.name == "Containment Impossible" && r.survivor == "Void Fiend") { return r.tier == 8; } return false; case "engineer-unqualified-personnel": if (r.skinId == "skinRodaniusEngineerUnqualifiedPersonnel_unqualified-personnel" && r.family == "single" && r.name == "Unqualified Personnel" && r.survivor == "Engineer") { return r.tier == 2; } return false; case "engineer-one-man-band": if (r.skinId == "skinEclipsePlaytestEngineerE3_one-man-band" && r.family == "single" && r.name == "One-Man Band" && r.survivor == "Engineer") { return r.tier == 3; } return false; case "engineer-castle-doctrine": if (r.skinId == "skinEclipsePlaytestEngineerE4_castle-doctrine" && r.family == "single" && r.name == "Castle Doctrine" && r.survivor == "Engineer") { return r.tier == 4; } return false; case "engineer-traffic-control": if (r.skinId == "skinEclipsePlaytestEngineerE5_traffic-control" && r.family == "single" && r.name == "Traffic Control" && r.survivor == "Engineer") { return r.tier == 5; } return false; case "engineer-bubble-works": if (r.skinId == "skinEclipsePlaytestEngineerE6_bubble-works" && r.family == "single" && r.name == "Bubble Works" && r.survivor == "Engineer") { return r.tier == 6; } return false; case "engineer-primitive-solutions": if (r.skinId == "skinEclipsePlaytestEngineerE7_primitive-solutions" && r.family == "single" && r.name == "Primitive Solutions" && r.survivor == "Engineer") { return r.tier == 7; } return false; case "engineer-orbital-architect": if (r.skinId == "skinEclipsePlaytestEngineerE8_orbital-architect" && r.family == "single" && r.name == "Orbital Architect" && r.survivor == "Engineer") { return r.tier == 8; } return false; default: return false; } } } [Serializable] public sealed class AssetFile { public string path; public string sha256; } [Serializable] public sealed class SkinRecord { public int schema; public int tier; public string key; public string name; public string survivor; public string family; public string skinId; public string assetDirectory; public string icon; public string iconSha256; public AssetFile[] files; [NonSerialized] public string Root; public string AssetRoot => SkinDiscovery.SafePath(Root, assetDirectory); } public static class SkinDiscovery { public static string SafePath(string root, string relative) { if (string.IsNullOrEmpty(relative) || Path.IsPathRooted(relative) || relative.Split('/', '\\').Any((string x) => x == ".." || x == "")) { throw new InvalidDataException("Invalid package-relative path"); } string text = Path.GetFullPath(root).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; string fullPath = Path.GetFullPath(Path.Combine(root, relative)); if (!fullPath.StartsWith(text, StringComparison.OrdinalIgnoreCase) && fullPath != text.TrimEnd(Path.DirectorySeparatorChar)) { throw new InvalidDataException("Package path escaped root"); } return fullPath; } private static IEnumerable<string> FindRecords(string root, Action<string> log) { Stack<string> todo = new Stack<string>(); todo.Push(root); while (todo.Count > 0) { string dir = todo.Pop(); string text = Path.Combine(dir, "rodanius-skin.json"); if (File.Exists(text)) { yield return text; } string[] directories; try { directories = Directory.GetDirectories(dir); } catch (Exception ex) { log("RODANIUS_DISCOVERY_SKIPPED " + dir + " " + ex.Message); continue; } string[] array = directories; foreach (string text2 in array) { try { if ((File.GetAttributes(text2) & FileAttributes.ReparsePoint) == 0) { todo.Push(text2); } } catch (Exception ex2) { log("RODANIUS_DISCOVERY_SKIPPED " + ex2.Message); } } } } public static string Hash(string path) { using FileStream inputStream = File.OpenRead(path); using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant(); } public static List<SkinRecord> Load(string family, Action<string> log, bool verifyAssets = true) { List<SkinRecord> list = new List<SkinRecord>(); foreach (string item in FindRecords(Paths.PluginPath, log)) { try { if (new FileInfo(item).Length > 262144) { throw new InvalidDataException("Manifest too large"); } SkinRecord skinRecord = JsonUtility.FromJson<SkinRecord>(File.ReadAllText(item)); if (skinRecord == null || skinRecord.schema != 1 || !CatalogueSpecs.Matches(skinRecord)) { throw new InvalidDataException("Unknown standalone skin identity"); } if (family != null && skinRecord.family != family) { continue; } skinRecord.Root = Path.GetDirectoryName(item); SafePath(skinRecord.Root, skinRecord.assetDirectory); SafePath(skinRecord.Root, skinRecord.icon); if (verifyAssets) { if (skinRecord.files == null || skinRecord.files.Length == 0 || skinRecord.files.Length > 100) { throw new InvalidDataException("Asset inventory missing"); } AssetFile[] files = skinRecord.files; foreach (AssetFile assetFile in files) { if (assetFile == null || assetFile.sha256 == null || assetFile.sha256.Length != 64 || Hash(SafePath(skinRecord.Root, assetFile.path)) != assetFile.sha256) { throw new InvalidDataException("Asset hash mismatch: " + ((assetFile == null) ? "null" : assetFile.path)); } } } list.Add(skinRecord); } catch (Exception ex) { log("RODANIUS_SKIN_PACKAGE_REJECTED file=" + item + " error=" + ex.Message); } } List<SkinRecord> list2 = new List<SkinRecord>(); foreach (IGrouping<string, SkinRecord> item2 in list.GroupBy<SkinRecord, string>((SkinRecord r) => r.skinId, StringComparer.Ordinal)) { if (item2.Count() != 1) { log("RODANIUS_DUPLICATE_SKIN_PACKAGE id=" + item2.Key + " paths=" + string.Join(";", item2.Select((SkinRecord r) => r.Root))); } else { list2.Add(item2.Single()); } } return list2.OrderBy<SkinRecord, string>((SkinRecord r) => r.survivor, StringComparer.Ordinal).ThenBy((SkinRecord r) => r.tier).ToList(); } } }