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 Void Fiend Skin Pack v0.1.0
BepInEx/plugins/VoidFiendBurntOffering/Eclipse.VoidFiend.E5.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE5 { [BepInPlugin("eclipseplaytest.void-fiend.e5", "Void Fiend - Burnt Offering (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendBurntOffering : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e5"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE5"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendBurntOffering instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E5_NAME", "Void Fiend - Burnt Offering (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendBurntOffering)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E5_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Burnt Offering skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Burnt Offering asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Burnt Offering asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Burnt Offering asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE5" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Burnt Offering asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E5_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE5")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE5" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE5"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE5"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E5_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<BurntOfferingFormSwitch>())) { modelPrefab.AddComponent<BurntOfferingFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E5_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<BurntOfferingFormSwitch>())) { ((Component)val).gameObject.AddComponent<BurntOfferingFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<BurntOfferingFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<BurntOfferingFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E5_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE5" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class BurntOfferingFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendBurntOffering.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendBurntOffering.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendBurntOffering.corruptedMesh) { target.sharedMesh = VoidFiendBurntOffering.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendBurntOffering.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendBurntOffering.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendBurntOffering.corruptedMesh : VoidFiendBurntOffering.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendContainmentImpossible/Eclipse.VoidFiend.E8.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE8 { [BepInPlugin("eclipseplaytest.void-fiend.e8", "Void Fiend - Containment Impossible (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendContainmentImpossible : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e8"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE8"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendContainmentImpossible instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E8_NAME", "Void Fiend - Containment Impossible (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendContainmentImpossible)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E8_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Containment Impossible skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Containment Impossible asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Containment Impossible asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Containment Impossible asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE8" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Containment Impossible asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E8_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE8")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE8" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE8"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE8"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E8_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<ContainmentImpossibleFormSwitch>())) { modelPrefab.AddComponent<ContainmentImpossibleFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E8_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<ContainmentImpossibleFormSwitch>())) { ((Component)val).gameObject.AddComponent<ContainmentImpossibleFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<ContainmentImpossibleFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<ContainmentImpossibleFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E8_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE8" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class ContainmentImpossibleFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendContainmentImpossible.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendContainmentImpossible.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendContainmentImpossible.corruptedMesh) { target.sharedMesh = VoidFiendContainmentImpossible.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendContainmentImpossible.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendContainmentImpossible.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendContainmentImpossible.corruptedMesh : VoidFiendContainmentImpossible.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendDesertCastaway/Eclipse.VoidFiend.E1.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE1 { [BepInPlugin("eclipseplaytest.void-fiend.e1", "Void Fiend - Desert Castaway (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendDesertCastaway : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e1"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE1"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendDesertCastaway instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E1_NAME", "Void Fiend - Desert Castaway (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendDesertCastaway)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E1_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Desert Castaway skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Desert Castaway asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Desert Castaway asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Desert Castaway asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE1" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Desert Castaway asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E1_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE1")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE1" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE1"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE1"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E1_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<DesertCastawayFormSwitch>())) { modelPrefab.AddComponent<DesertCastawayFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E1_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<DesertCastawayFormSwitch>())) { ((Component)val).gameObject.AddComponent<DesertCastawayFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<DesertCastawayFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<DesertCastawayFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E1_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE1" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class DesertCastawayFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendDesertCastaway.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendDesertCastaway.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendDesertCastaway.corruptedMesh) { target.sharedMesh = VoidFiendDesertCastaway.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendDesertCastaway.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendDesertCastaway.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendDesertCastaway.corruptedMesh : VoidFiendDesertCastaway.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendLiveWire/Eclipse.VoidFiend.E2.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE2 { [BepInPlugin("eclipseplaytest.void-fiend.e2", "Void Fiend - Live Wire (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendLiveWire : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e2"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE2"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendLiveWire instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E2_NAME", "Void Fiend - Live Wire (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendLiveWire)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E2_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Live Wire skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Live Wire asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Live Wire asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Live Wire asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE2" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Live Wire asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E2_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE2")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE2" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE2"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE2"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E2_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<LiveWireFormSwitch>())) { modelPrefab.AddComponent<LiveWireFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E2_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<LiveWireFormSwitch>())) { ((Component)val).gameObject.AddComponent<LiveWireFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<LiveWireFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<LiveWireFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E2_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE2" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class LiveWireFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendLiveWire.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendLiveWire.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendLiveWire.corruptedMesh) { target.sharedMesh = VoidFiendLiveWire.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendLiveWire.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendLiveWire.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendLiveWire.corruptedMesh : VoidFiendLiveWire.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendOrangeYouGlad/Eclipse.VoidFiend.E4.OrangeYouGlad.dll
Decompiled a week 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 UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE4 { [BepInPlugin("eclipseplaytest.void-fiend.e4", "Void Fiend - Orange You Glad (Playtest)", "0.1.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendOrange : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e4"; public const string Version = "0.1.3"; public const string SkinId = "skinEclipsePlaytestVoidFiendE4"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendOrange instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E4_NAME", "Void Fiend - Orange You Glad (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendOrange)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E4_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the orange skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid orange asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Orange asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Orange asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "orange-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE4" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid orange asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E4_REGISTRATION_BEGIN version=0.1.3 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE4")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE4" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE4"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE4"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E4_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<OrangeFormSwitch>())) { modelPrefab.AddComponent<OrangeFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E4_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<OrangeFormSwitch>())) { ((Component)val).gameObject.AddComponent<OrangeFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<OrangeFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<OrangeFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E4_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Expected O, but got Unknown //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE4" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class OrangeFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsOrange() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendOrange.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendOrange.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendOrange.corruptedMesh) { target.sharedMesh = VoidFiendOrange.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsOrange()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendOrange.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendOrange.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendOrange.corruptedMesh : VoidFiendOrange.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendPressureGuest/Eclipse.VoidFiend.E3.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE3 { [BepInPlugin("eclipseplaytest.void-fiend.e3", "Void Fiend - Pressure Guest (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendPressureGuest : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public string materialMode; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e3"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE3"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendPressureGuest instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E3_NAME", "Void Fiend - Pressure Guest (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendPressureGuest)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E3_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Pressure Guest skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Pressure Guest asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Pressure Guest asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Pressure Guest asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE3" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Pressure Guest asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E3_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE3")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); if (manifest.materialMode != "native-dither-translucency") { throw new InvalidDataException("Pressure Guest requires its coverage atlas"); } AsyncOperationHandle<Shader> transparentOp = Addressables.LoadAssetAsync<Shader>((object)"RoR2/Base/Shaders/HGStandardTransparent.shader"); retainedAssets.Add(AsyncOperationHandle<Shader>.op_Implicit(transparentOp)); while (!transparentOp.IsDone) { CheckDeadline("translucent mantle shader"); yield return null; } if (!Object.op_Implicit((Object)(object)transparentOp.Result)) { throw new InvalidOperationException("Native translucent shader unavailable"); } Material val4 = new Material(transparentOp.Result) { name = "matEclipsePlaytestVoidFiendE3" }; if (!val4.HasProperty("_useDither") || !val4.HasProperty("_ForceSpecOn")) { throw new InvalidOperationException("Unsupported native translucent shader"); } val4.EnableKeyword("USE_DITHER"); val4.SetFloat("_useDither", 1f); val4.DisableKeyword("USE_BLUE"); val4.SetFloat("_useBlue", 0f); val4.EnableKeyword("FORCE_SPEC"); val4.SetFloat("_ForceSpecOn", 1f); val4.SetFloat("_AlphaContrast", 1f); val4.SetFloat("_AlphaMidPoint", 0.5f); val4.SetFloat("_RampInfo", 4f); val4.SetFloat("_Cull", 2f); val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE3"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE3"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E3_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<PressureGuestFormSwitch>())) { modelPrefab.AddComponent<PressureGuestFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E3_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<PressureGuestFormSwitch>())) { ((Component)val).gameObject.AddComponent<PressureGuestFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<PressureGuestFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<PressureGuestFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E3_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE3" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class PressureGuestFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendPressureGuest.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendPressureGuest.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendPressureGuest.corruptedMesh) { target.sharedMesh = VoidFiendPressureGuest.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendPressureGuest.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendPressureGuest.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendPressureGuest.corruptedMesh : VoidFiendPressureGuest.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendPublicInformation/Eclipse.VoidFiend.E6.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE6 { [BepInPlugin("eclipseplaytest.void-fiend.e6", "Void Fiend - Public Information (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendPublicInformation : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e6"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE6"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendPublicInformation instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E6_NAME", "Void Fiend - Public Information (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendPublicInformation)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E6_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Public Information skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Public Information asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Public Information asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Public Information asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE6" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Public Information asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E6_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE6")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE6" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE6"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE6"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E6_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<PublicInformationFormSwitch>())) { modelPrefab.AddComponent<PublicInformationFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E6_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<PublicInformationFormSwitch>())) { ((Component)val).gameObject.AddComponent<PublicInformationFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<PublicInformationFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<PublicInformationFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E6_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE6" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class PublicInformationFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendPublicInformation.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendPublicInformation.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendPublicInformation.corruptedMesh) { target.sharedMesh = VoidFiendPublicInformation.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendPublicInformation.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendPublicInformation.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendPublicInformation.corruptedMesh : VoidFiendPublicInformation.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }
BepInEx/plugins/VoidFiendSurpriseInside/Eclipse.VoidFiend.E7.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using EclipseSkinRuntimeFix; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EclipseSkinRuntimeFix { internal static class NativeRenderers { private static readonly HashSet<string> NativePaths = new HashSet<string>(StringComparer.Ordinal) { "mdlLoader/PilotFemaleMesh", "mdlLoader/LoaderMechMesh", "mdlLoader/PilotFemaleFoldedOverJumpsuit", "mdlFalseSon/FalseSon_Body", "mdlFalseSon/FalseSon_Cloth", "mdlFalseSon/L_FalseSon_Weapon", "mdlSeeker/meshSeekerBody", "mdlSeeker/meshSeekerCloth", "mdlSeeker/meshSeekerGlass", "mdlChef/meshChef", "mdlChef/meshChefPizzaCutter", "mdlChef/meshlChefCleaver", "mdlChef/meshChefOven", "mdlChef/meshChefIceBox", "mdlCroco/CrocoMesh", "mdlCroco/CrocoSpineMesh", "mdlHuntress/HuntressMesh", "mdlHuntress/BowMesh", "mdlHuntress/HuntressScarfMesh", "mdlHuntress (1)/HuntressMesh", "mdlHuntress (1)/BowMesh", "mdlHuntress (1)/HuntressScarfMesh", "mdlMerc/MercMesh", "mdlMerc/MercSwordMesh", "mdlTreebot/TreebotBotMesh", "mdlTreebot/TreebotRootMesh", "mdlTreebot/TreebotLeafletMesh", "mdlTreebot/TreebotFlowerMesh", "mdlVoidSurvivor/mdlVoidSurvivorBody", "mdlVoidSurvivor/mdlVoidSurvivorHead", "mdlVoidSurvivor/mdlVoidSurvivorMetal", "mdlVoidSurvivor/metalcollar.001", "mdlBandit2/BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", "mdlBandit2/BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", "mdlBandit2/Bandit2AccessoriesMesh" }; public static T[] GetSkinRenderers<T>(this Component owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { return owner.gameObject.GetSkinRenderers<T>(inactive, parameters); } public static T[] GetSkinRenderers<T>(this GameObject owner, bool inactive = false, SkinDefParams parameters = null) where T : Renderer { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) T[] componentsInChildren = owner.GetComponentsInChildren<T>(inactive); CharacterModel val = owner.GetComponent<CharacterModel>() ?? owner.GetComponentInParent<CharacterModel>(); ModelSkinController val2 = owner.GetComponent<ModelSkinController>() ?? (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ModelSkinController>() : null); HashSet<Renderer> skinRefs = new HashSet<Renderer>(); SkinDefParams val3 = parameters; if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val2) && val2.skins != null && val2.skins.Length != 0 && Object.op_Implicit((Object)(object)val2.skins[0])) { val3 = val2.skins[0].skinDefParams; } if (Object.op_Implicit((Object)(object)val3)) { if (val3.rendererInfos != null) { RendererInfo[] rendererInfos = val3.rendererInfos; foreach (RendererInfo val4 in rendererInfos) { if (Object.op_Implicit((Object)(object)val4.renderer)) { skinRefs.Add(val4.renderer); } } } if (val3.meshReplacements != null) { MeshReplacement[] meshReplacements = val3.meshReplacements; foreach (MeshReplacement val5 in meshReplacements) { if (Object.op_Implicit((Object)(object)val5.renderer)) { skinRefs.Add(val5.renderer); } } } } HashSet<Renderer> modelRefs = new HashSet<Renderer>(); if (Object.op_Implicit((Object)(object)val) && val.baseRendererInfos != null) { RendererInfo[] rendererInfos = val.baseRendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer)) { modelRefs.Add(val6.renderer); } } } return Select(componentsInChildren, (T x) => ((Object)(object)x).name, (T x) => skinRefs.Contains((Renderer)(object)x), (T x) => modelRefs.Contains((Renderer)(object)x), (T x) => Path(((Component)(object)x).transform, owner.transform), (T x) => IsKnownNativePath(Path(((Component)(object)x).transform, owner.transform))); } internal static T[] Select<T>(T[] found, Func<T, string> name, Func<T, bool> skin, Func<T, bool> model, Func<T, string> path, Func<T, bool> contract = null) { HashSet<T> hashSet = new HashSet<T>(); if (contract == null) { contract = (T x) => false; } bool flag = found.Any(skin) || found.Any(model) || found.Any(contract); foreach (IGrouping<string, T> item in found.GroupBy(name)) { T[] array = item.ToArray(); if (array.Length == 1) { if (!flag || skin(array[0]) || model(array[0]) || contract(array[0])) { hashSet.Add(array[0]); } continue; } T[] array2 = array.Where(skin).ToArray(); T[] array3 = array.Where(model).ToArray(); T[] array4 = ((array2.Length == 1) ? ((array3.Length == 0 || array3.Contains(array2[0])) ? array2 : new T[0]) : ((array2.Length <= 1) ? array3 : array2.Where(((IEnumerable<T>)array3).Contains<T>).ToArray())); if (array2.Length == 0 && array3.Length == 0) { T[] array5 = array.Where(contract).ToArray(); if (array5.Length != 0) { if (array5.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_PATH_AMBIGUOUS " + string.Join(";", array.Select(path))); } hashSet.Add(array5[0]); Debug.Log((object)("ECLIPSE_RENDERER_NATIVE_PATH name=" + item.Key + " native=" + path(array5[0]))); continue; } } if (array2.Length == 0 && array3.Length == 0 && flag) { Debug.Log((object)("ECLIPSE_RENDERER_FOREIGN_DUPLICATES name=" + item.Key + " ignored=" + array.Length)); continue; } if (array4.Length != 1) { throw new InvalidOperationException("ECLIPSE_RENDERER_AMBIGUOUS name=" + item.Key + " candidates=" + string.Join(";", array.Select(path)) + " skinRefs=" + array2.Length + " modelRefs=" + array3.Length); } hashSet.Add(array4[0]); Debug.Log((object)("ECLIPSE_RENDERER_RESOLVED name=" + item.Key + " native=" + path(array4[0]) + " ignoredDuplicates=" + (array.Length - 1))); } return found.Where(hashSet.Contains).ToArray(); } internal static bool IsKnownNativePath(string path) { if (path == null) { return false; } int num = path.IndexOf('/'); if (num < 0) { return false; } string text = path.Substring(0, num); if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } return NativePaths.Contains(text + path.Substring(num)); } private static string Path(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } } } namespace EclipsePlaytestVoidFiendE7 { [BepInPlugin("eclipseplaytest.void-fiend.e7", "Void Fiend - Surprise Inside (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class VoidFiendSurpriseInside : BaseUnityPlugin { [Serializable] public sealed class AssetFile { public string file; public string sha256; } [Serializable] public sealed class AssetManifest { public int schema; public string skinId; public string revision; public AssetFile calm; public AssetFile corrupted; public AssetFile albedo; public AssetFile emission; public AssetFile icon; } public const string Guid = "eclipseplaytest.void-fiend.e7"; public const string Version = "0.1.2"; public const string SkinId = "skinEclipsePlaytestVoidFiendE7"; private const string BodyName = "VoidSurvivorBody"; private const string Target = "mdlVoidSurvivorBody"; private static readonly string[] Hidden = new string[3] { "mdlVoidSurvivorHead", "mdlVoidSurvivorMetal", "metalcollar.001" }; private static VoidFiendSurpriseInside instance; internal static Mesh calmMesh; internal static Mesh corruptedMesh; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private AssetManifest manifest; private GameObject modelPrefab; private SkinDef skin; private string folder; private float deadline; private bool registered; internal static SkinDef ActiveSkin { get { if (!Object.op_Implicit((Object)(object)instance)) { return null; } return instance.skin; } } private static bool registered_ { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.registered; } return false; } } private void Awake() { instance = this; folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); LanguageAPI.Add("ECLIPSEPLAYTEST_VOIDFIEND_E7_NAME", "Void Fiend - Surprise Inside (Playtest)"); SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(VoidFiendSurpriseInside)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; CharacterBody.onBodyStartGlobal += AttachFormSwitch; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.deadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.Register(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("VOIDFIEND_E7_REGISTRATION_FAILED " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private void CheckDeadline(string what) { if (Time.realtimeSinceStartup > deadline) { throw new TimeoutException("Stopped loading " + what + "; startup continues without the Surprise Inside skin."); } } private byte[] ReadAsset(AssetFile entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.file) || Path.GetFileName(entry.file) != entry.file || entry.sha256 == null || entry.sha256.Length != 64) { throw new InvalidDataException("Invalid Surprise Inside asset entry"); } string text = Path.Combine(folder, entry.file); if (new FileInfo(text).Length > 67108864) { throw new InvalidDataException("Surprise Inside asset too large"); } byte[] array = File.ReadAllBytes(text); using SHA256 sHA = SHA256.Create(); if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != entry.sha256) { throw new InvalidDataException("Surprise Inside asset hash mismatch: " + entry.file); } return array; } private IEnumerator Register() { manifest = JsonUtility.FromJson<AssetManifest>(File.ReadAllText(Path.Combine(folder, "skin-assets.json"))); if (manifest == null || manifest.schema != 1 || manifest.skinId != "skinEclipsePlaytestVoidFiendE7" || string.IsNullOrWhiteSpace(manifest.revision)) { throw new InvalidDataException("Invalid Surprise Inside asset identity"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E7_REGISTRATION_BEGIN version=0.1.2 revision=" + manifest.revision)); GameObject val = BodyCatalog.FindBodyPrefab("VoidSurvivorBody"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ModelLocator>())) { throw new InvalidOperationException("VoidSurvivorBody missing"); } modelPrefab = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = modelPrefab.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || controller.skins.Length == 0) { throw new InvalidOperationException("Void Fiend base skin missing"); } if (controller.skins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "skinEclipsePlaytestVoidFiendE7")) { yield break; } SkinDef baseSkin = controller.skins[0]; SkinDefParams baseParams = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)baseParams) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> op = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(op)); while (!op.IsDone) { CheckDeadline("base parameters"); yield return null; } baseParams = op.Result; } if (!Object.op_Implicit((Object)(object)baseParams)) { throw new InvalidOperationException("Void Fiend base parameters unavailable"); } Renderer[] renderers = modelPrefab.GetSkinRenderers<Renderer>(inactive: true, baseParams); SkinnedMeshRenderer target = renderers.OfType<SkinnedMeshRenderer>().Single((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody"); if (target.bones.Length != 71 || target.bones.Any((Transform b) => !Object.op_Implicit((Object)(object)b)) || target.bones.Select((Transform b) => ((Object)b).name).Distinct().Count() != 71) { throw new InvalidOperationException("Unexpected Void Fiend skeleton: " + target.bones.Length); } Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = ((IEnumerable<MeshReplacement>)baseParams.meshReplacements).FirstOrDefault((Func<MeshReplacement, bool>)((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target)); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Mesh> op2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(op2)); while (!op2.IsDone) { CheckDeadline("native bind mesh"); yield return null; } reference = op2.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 71) { throw new InvalidOperationException("Native bindposes unavailable or mismatched"); } RendererInfo info = baseParams.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = info.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> op3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(op3)); while (!op3.IsDone) { CheckDeadline("native material"); yield return null; } val3 = op3.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Native Void Fiend shader unavailable"); } calmMesh = ReadMesh(ReadAsset(manifest.calm), target, reference, "Calm"); corruptedMesh = ReadMesh(ReadAsset(manifest.corrupted), target, reference, "Corrupted"); Material val4 = new Material(val3) { name = "matEclipsePlaytestVoidFiendE7" }; val4.SetTexture("_MainTex", (Texture)(object)ReadTexture(manifest.albedo, linear: false)); val4.SetColor("_Color", Color.white); val4.DisableKeyword("FRESNEL_EMISSION"); val4.SetFloat("_FEON", 0f); val4.SetTexture("_FresnelMask", (Texture)null); val4.SetTexture("_FresnelRamp", (Texture)null); val4.DisableKeyword("LIMBREMOVAL"); val4.SetFloat("_LimbRemovalOn", 0f); val4.SetTexture("_NormalTex", (Texture)null); val4.SetFloat("_NormalStrength", 0f); val4.SetFloat("_Smoothness", 0.35f); val4.SetFloat("_SpecularStrength", 0.35f); val4.SetFloat("_SpecularExponent", 10f); val4.SetTexture("_EmTex", (Texture)(object)ReadTexture(manifest.emission, linear: false)); val4.SetColor("_EmColor", Color.white); val4.SetFloat("_EmPower", 1.5f); RendererInfo val5 = info; val5.renderer = (Renderer)(object)target; val5.defaultMaterial = val4; val5.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val6).name = "paramsEclipsePlaytestVoidFiendE7"; val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { val5 }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = calmMesh, meshAddress = new AssetReferenceT<Mesh>("") } }; val6.gameObjectActivations = ((IEnumerable<string>)Hidden).Select((Func<string, GameObjectActivation>)((string n) => new GameObjectActivation { gameObject = ((Component)renderers.Single((Renderer r) => ((Object)r).name == n)).gameObject, shouldActivate = false })).ToArray(); val6.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); val6.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); val6.lightReplacements = Array.Empty<LightInfo>(); skin = ScriptableObject.CreateInstance<SkinDef>(); ((Object)skin).name = "skinEclipsePlaytestVoidFiendE7"; skin.nameToken = "ECLIPSEPLAYTEST_VOIDFIEND_E7_NAME"; skin.icon = ((manifest.icon != null && !string.IsNullOrEmpty(manifest.icon.file)) ? ReadIcon(manifest.icon) : CreateIcon()); skin.unlockableDef = null; skin.rootObject = modelPrefab; skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; skin.skinDefParams = val6; controller.skins = controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { skin }).ToArray(); registered = true; if (!Object.op_Implicit((Object)(object)modelPrefab.GetComponent<SurpriseInsideFormSwitch>())) { modelPrefab.AddComponent<SurpriseInsideFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E7_REGISTERED revision=" + manifest.revision + " calmTris=" + calmMesh.triangles.Length / 3 + " corruptedTris=" + corruptedMesh.triangles.Length / 3)); } private static void AttachFormSwitch(CharacterBody body) { if (registered_ && Object.op_Implicit((Object)(object)body) && ((Object)body).name.IndexOf("VoidSurvivorBody", StringComparison.Ordinal) == 0) { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<SurpriseInsideFormSwitch>())) { ((Component)val).gameObject.AddComponent<SurpriseInsideFormSwitch>(); } } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "VoidSurvivorBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<SurpriseInsideFormSwitch>())) { ((Component)componentInChildren).gameObject.AddComponent<SurpriseInsideFormSwitch>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("VOIDFIEND_E7_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(AssetFile entry, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear) { name = entry.file, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return val; } private Sprite ReadIcon(AssetFile entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = entry.file }; if (!ImageConversion.LoadImage(val, ReadAsset(entry), false)) { throw new InvalidDataException("Cannot decode " + entry.file); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static Sprite CreateIcon() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[4] { new Color32((byte)242, (byte)112, (byte)18, byte.MaxValue), new Color32((byte)236, (byte)214, (byte)160, byte.MaxValue), new Color32((byte)140, (byte)196, (byte)40, byte.MaxValue), new Color32((byte)92, (byte)24, (byte)140, byte.MaxValue) }; Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array2[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : array[num]); } } val.SetPixels32(array2); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised -= SyncDisplaySkins; CharacterBody.onBodyStartGlobal -= AttachFormSwitch; if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static byte[] DecodeMeshPayload(byte[] data) { if (data == null) { throw new InvalidDataException("Missing mesh payload"); } if (data.Length < 2 || data[0] != 31 || data[1] != 139) { return data; } using MemoryStream stream = new MemoryStream(data, writable: false); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int num; while ((num = gZipStream.Read(array, 0, array.Length)) != 0) { if (memoryStream.Length + num > 33554432) { throw new InvalidDataException("Decoded mesh exceeds limit"); } memoryStream.Write(array, 0, num); } return memoryStream.ToArray(); } private static Mesh ReadMesh(byte[] data, SkinnedMeshRenderer renderer, Mesh reference, string form) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) data = DecodeMeshPayload(data); using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data, writable: false)); if (new string(binaryReader.ReadChars(4)) != "PWE1") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 300000 || num2 < 3 || num2 > 1500000 || num2 % 3 != 0 || num3 != 71) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); if (!hashSet.Add(name)) { throw new InvalidDataException("Duplicate payload bone: " + name); } array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0) { throw new InvalidDataException("Missing reference bone: " + name); } } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int num5 = 0; num5 < num; num5++) { array2[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[num5] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); if (!Finite(array2[num5].x) || !Finite(array2[num5].y) || !Finite(array2[num5].z) || !Finite(array3[num5].x) || !Finite(array3[num5].y) || !Finite(array3[num5].z) || !Finite(array4[num5].x) || !Finite(array4[num5].y)) { throw new InvalidDataException("Nonfinite vertex"); } int[] array6 = new int[4]; for (int num6 = 0; num6 < 4; num6++) { int num7 = binaryReader.ReadInt32(); if (num7 < 0 || num7 >= num3) { throw new InvalidDataException("Bone out of range."); } array6[num6] = array[num7]; } float[] array7 = new float[4]; for (int num8 = 0; num8 < 4; num8++) { array7[num8] = binaryReader.ReadSingle(); } if (array7.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array7.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } int num9 = num5; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = array6[0]; ((BoneWeight)(ref val)).boneIndex1 = array6[1]; ((BoneWeight)(ref val)).boneIndex2 = array6[2]; ((BoneWeight)(ref val)).boneIndex3 = array6[3]; ((BoneWeight)(ref val)).weight0 = array7[0]; ((BoneWeight)(ref val)).weight1 = array7[1]; ((BoneWeight)(ref val)).weight2 = array7[2]; ((BoneWeight)(ref val)).weight3 = array7[3]; array5[num9] = val; } int[] array8 = new int[num2]; for (int num10 = 0; num10 < num2; num10++) { array8[num10] = binaryReader.ReadInt32(); if (array8[num10] < 0 || array8[num10] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val2 = new Mesh { name = "meshEclipsePlaytestVoidFiendE7" + form, indexFormat = (IndexFormat)(num > 65535), vertices = array2, normals = array3, uv = array4, boneWeights = array5, bindposes = reference.bindposes, triangles = array8 }; val2.RecalculateBounds(); val2.RecalculateTangents(); return val2; } } public sealed class SurpriseInsideFormSwitch : MonoBehaviour { private CharacterBody body; private ModelSkinController controller; private SkinnedMeshRenderer target; private bool subscribed; private bool acquired; private bool previousOffscreen; private Bounds previousBounds; private Bounds ownedBounds; private void OnEnable() { Subscribe(); } private void Subscribe() { if (!subscribed) { controller = ((Component)this).GetComponent<ModelSkinController>(); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; subscribed = true; } body = ((Component)this).GetComponentInParent<CharacterBody>(); } } private void Applied(int index) { Release(); } private bool IsSelectedSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null || !Object.op_Implicit((Object)(object)VoidFiendSurpriseInside.ActiveSkin)) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length) { return (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)VoidFiendSurpriseInside.ActiveSkin; } return false; } private void Release() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (acquired && Object.op_Implicit((Object)(object)target)) { if (((Renderer)target).localBounds == ownedBounds) { ((Renderer)target).localBounds = previousBounds; } if (target.updateWhenOffscreen) { target.updateWhenOffscreen = previousOffscreen; } if ((Object)(object)target.sharedMesh == (Object)(object)VoidFiendSurpriseInside.corruptedMesh) { target.sharedMesh = VoidFiendSurpriseInside.calmMesh; } } acquired = false; } private void LateUpdate() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Subscribe(); if (!IsSelectedSkin()) { Release(); return; } if (!Object.op_Implicit((Object)(object)target)) { target = ((IEnumerable<SkinnedMeshRenderer>)((Component)(object)this).GetSkinRenderers<SkinnedMeshRenderer>(inactive: true, (SkinDefParams)null)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "mdlVoidSurvivorBody")); } if (!Object.op_Implicit((Object)(object)target) || ((Object)(object)target.sharedMesh != (Object)(object)VoidFiendSurpriseInside.calmMesh && (Object)(object)target.sharedMesh != (Object)(object)VoidFiendSurpriseInside.corruptedMesh)) { Release(); return; } if (!acquired) { previousBounds = ((Renderer)target).localBounds; previousOffscreen = target.updateWhenOffscreen; ownedBounds = new Bounds(((Bounds)(ref previousBounds)).center, new Vector3(6f, 6f, 6f)); ((Renderer)target).localBounds = ownedBounds; target.updateWhenOffscreen = true; acquired = true; } Mesh val = ((Object.op_Implicit((Object)(object)body) && body.HasBuff(Buffs.VoidSurvivorCorruptMode)) ? VoidFiendSurpriseInside.corruptedMesh : VoidFiendSurpriseInside.calmMesh); if ((Object)(object)target.sharedMesh != (Object)(object)val) { target.sharedMesh = val; } } private void OnDisable() { Release(); if (subscribed && Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } subscribed = false; } } }