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 Delloom v0.5.6
BepInEx/plugins/Delloom/LoomReskin.dll
Decompiled 7 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LoomReskin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.6.0")] [assembly: AssemblyInformationalVersion("0.5.6")] [assembly: AssemblyProduct("LoomReskin")] [assembly: AssemblyTitle("LoomReskin")] [assembly: AssemblyMetadata("AI_Assisted_Creation", "Code and development tooling were created with assistance from OpenAI Codex and Anthropic Claude (Sonnet).")] [assembly: AssemblyMetadata("AI_Model_Vendor", "OpenAI; Anthropic")] [assembly: AssemblyMetadata("AI_Agents", "OpenAI Codex; Anthropic Claude (Sonnet)")] [assembly: AssemblyVersion("0.5.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LoomReskin { [BepInPlugin("local.lemon.loomreskin", "Lady in Red — Loom", "0.5.6")] public sealed class Plugin : BaseUnityPlugin { internal static Plugin Instance; private Harmony patches; private JewelryAsset jewelry; private bool ready; private bool validationRun; private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown GameObject gameObject = ((Component)this).gameObject; ((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x3D); Instance = this; try { jewelry = AssetLoader.Parse(File.ReadAllText(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "visuals.json"))); patches = new Harmony("local.lemon.loomreskin"); patches.PatchAll(typeof(Plugin).Assembly); ready = true; SceneManager.sceneLoaded += OnSceneLoaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Ready: EnemyShadow visual reskin; original AI, colliders, transforms, and animation controllers retained."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Reskin disabled: " + ex)); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (!ready || validationRun) { return; } validationRun = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Validating original Loom hierarchy after scene load: " + ((Scene)(ref scene)).name)); try { SelfCheck(); } catch (Exception ex) { ready = false; patches.UnpatchSelf(); ((BaseUnityPlugin)this).Logger.LogError((object)("Validation failed; instance patch disabled: " + ex)); } } internal void ApplyLive(Transform root) { if (!ready) { return; } try { int num = Visuals.Apply(root, jewelry, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); if (num > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Applied Loom reskin: " + num + " original renderers styled; " + jewelry.parts.Length + " accessory and hair mesh pieces.")); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Loom instance left unchanged because its layout was not supported: " + ex)); } } private void SelfCheck() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) GameObject val = Resources.Load<GameObject>("enemies/enemy - shadow"); if ((Object)(object)val == (Object)null) { throw new Exception("Original Loom prefab unavailable."); } EnemyShadow componentInChildren = val.GetComponentInChildren<EnemyShadow>(true); if ((Object)(object)componentInChildren == (Object)null || (Object)(object)SpawnPatch.VisualRoot(componentInChildren) != (Object)(object)val.transform) { throw new Exception("Live spawn hook does not resolve the original prefab root."); } GameObject val2 = new GameObject("LoomReskin verification"); val2.SetActive(false); try { CopyVisualTree(val.transform, val2.transform); Transform[] componentsInChildren = val2.GetComponentsInChildren<Transform>(true); Vector3[] array = componentsInChildren.Select((Transform t) => t.localPosition).ToArray(); Quaternion[] array2 = componentsInChildren.Select((Transform t) => t.localRotation).ToArray(); Vector3[] array3 = componentsInChildren.Select((Transform t) => t.localScale).ToArray(); MeshRenderer[] componentsInChildren2 = val2.GetComponentsInChildren<MeshRenderer>(true); Material[] array4 = componentsInChildren2.Select((MeshRenderer r) => ((Renderer)r).sharedMaterial).ToArray(); Mesh[] first = (from m in val2.GetComponentsInChildren<MeshFilter>(true) select m.sharedMesh).ToArray(); int num = Visuals.Apply(val2.transform, jewelry, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); foreach (MeshRenderer item in from r in val2.GetComponentsInChildren<MeshRenderer>(true) where ((Object)r).name.StartsWith("LoomJewelry_") select r) { Material sharedMaterial = ((Renderer)item).sharedMaterial; if ((Object)(object)sharedMaterial.GetTexture("_EmissionTexture") != (Object)null || sharedMaterial.GetColor("_EmissionColor") != Color.black) { throw new Exception("Authored material inherited original emission: " + ((Object)item).name); } if (sharedMaterial.GetFloat("_NormalStrength") != 0f || sharedMaterial.GetFloat("_OffsetX") != 0f || sharedMaterial.GetFloat("_OffsetY") != 0f) { throw new Exception("Authored material inherited normal strength or UV offset: " + ((Object)item).name); } if (sharedMaterial.GetFloat("_TilingX") != 1f || sharedMaterial.GetFloat("_TilingY") != 1f) { throw new Exception("Authored material has unexpected UV tiling: " + ((Object)item).name); } } int num2 = ((jewelry.schemaVersion == 2) ? 30 : 15); if (num != num2) { throw new Exception("Expected " + num2 + " targeted renderers; found " + num + "."); } for (int num3 = 0; num3 < componentsInChildren.Length; num3++) { if (componentsInChildren[num3].localPosition != array[num3] || componentsInChildren[num3].localRotation != array2[num3] || componentsInChildren[num3].localScale != array3[num3]) { throw new Exception("Original pivot modified: " + ((Object)componentsInChildren[num3]).name); } } for (int num4 = 0; num4 < componentsInChildren2.Length; num4++) { if (VisualSelection.Classify(Visuals.PathOf(((Component)componentsInChildren2[num4]).transform, val2.transform)) == VisualKind.Original && (Object)(object)((Renderer)componentsInChildren2[num4]).sharedMaterial != (Object)(object)array4[num4]) { throw new Exception("Untargeted renderer changed: " + ((Object)componentsInChildren2[num4]).name); } } Mesh[] second = (from m in val2.GetComponentsInChildren<MeshFilter>(true) where !((Object)m).name.StartsWith("LoomJewelry_") select m.sharedMesh).ToArray(); if (!first.SequenceEqual(second)) { throw new Exception("Original meshes changed."); } JewelryPart[] parts = jewelry.parts; foreach (JewelryPart jewelryPart in parts) { if (VisualSelection.Classify(jewelryPart.parentPath) == VisualKind.Clothing || jewelryPart.replacesParentRenderer) { MeshRenderer component = ((Component)val2.transform.Find(jewelryPart.parentPath)).GetComponent<MeshRenderer>(); OwnedVisuals component2 = val2.GetComponent<OwnedVisuals>(); int index = component2.renderers.IndexOf(component); if (((Renderer)((Component)val2.transform.Find(jewelryPart.parentPath + "/LoomJewelry_" + jewelryPart.name)).GetComponent<MeshRenderer>()).enabled != (jewelryPart.enabled && component2.enabledStates[index])) { throw new Exception("Original replacement visibility not preserved: " + jewelryPart.name); } if (jewelryPart.replacesParentRenderer && ((Renderer)component).enabled) { throw new Exception("Replaced face renderer is still visible: " + jewelryPart.name); } } } int num6 = val2.GetComponentsInChildren<Transform>(true).Length; if (Visuals.Apply(val2.transform, jewelry, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)) != 0 || val2.GetComponentsInChildren<Transform>(true).Length != num6) { throw new Exception("Repeated application duplicated accessories."); } try { PreviewCapture.Save(val2, Path.Combine(Paths.BepInExRootPath, "LoomReskinPreview")); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Saved runtime render previews to BepInEx/LoomReskinPreview."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Preview capture unavailable: " + ex.Message)); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("SELF-CHECK PASS: " + num2 + " targeted renderers; original meshes and all " + componentsInChildren.Length + " pivots preserved; authored visual parents resolved; repeated application safe.")); } finally { Object.Destroy((Object)(object)val2); } } private static void CopyVisualTree(Transform source, Transform dest) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in source) { Transform val = item; GameObject val2 = new GameObject(((Object)val).name); val2.transform.SetParent(dest, false); val2.transform.localPosition = val.localPosition; val2.transform.localRotation = val.localRotation; val2.transform.localScale = val.localScale; MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); MeshRenderer component2 = ((Component)val).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { val2.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; MeshRenderer obj = val2.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterials = ((Renderer)component2).sharedMaterials; ((Renderer)obj).enabled = ((Renderer)component2).enabled; } CopyVisualTree(val, val2.transform); val2.SetActive(((Component)val).gameObject.activeSelf); } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; Harmony obj = patches; if (obj != null) { obj.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(EnemyShadow), "Awake")] internal static class SpawnPatch { internal static Transform VisualRoot(EnemyShadow instance) { EnemyParent componentInParent = ((Component)instance).GetComponentInParent<EnemyParent>(true); if (componentInParent == null) { return null; } return ((Component)componentInParent).transform; } [HarmonyPostfix] private static void Postfix(EnemyShadow __instance) { Transform val = VisualRoot(__instance); if ((Object)(object)val != (Object)null) { Plugin.Instance?.ApplyLive(val); } } } internal sealed class OwnedVisuals : MonoBehaviour { internal readonly List<Object> assets = new List<Object>(); internal readonly List<GameObject> additions = new List<GameObject>(); internal readonly List<MeshRenderer> renderers = new List<MeshRenderer>(); internal readonly List<Material> originals = new List<Material>(); internal readonly List<bool> enabledStates = new List<bool>(); private void OnDestroy() { for (int i = 0; i < renderers.Count; i++) { if ((Object)(object)renderers[i] != (Object)null) { ((Renderer)renderers[i]).sharedMaterial = originals[i]; ((Renderer)renderers[i]).enabled = enabledStates[i]; } } foreach (GameObject addition in additions) { if ((Object)(object)addition != (Object)null) { Object.Destroy((Object)(object)addition); } } foreach (Object asset in assets) { if (asset != (Object)null) { Object.Destroy(asset); } } } } internal static class Visuals { internal static string PathOf(Transform t, Transform root) { List<string> list = new List<string>(); while ((Object)(object)t != (Object)(object)root && (Object)(object)t != (Object)null) { list.Add(((Object)t).name); t = t.parent; } list.Reverse(); return string.Join("/", list); } internal static int Apply(Transform root, JewelryAsset jewelry, string assetDirectory) { //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Expected O, but got Unknown //IL_0369: 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_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Expected O, but got Unknown //IL_082f: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Expected O, but got Unknown //IL_0889: Unknown result type (might be due to invalid IL or missing references) //IL_088e: Unknown result type (might be due to invalid IL or missing references) //IL_089d: Expected O, but got Unknown //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_0697: Unknown result type (might be due to invalid IL or missing references) //IL_0719: Unknown result type (might be due to invalid IL or missing references) //IL_0720: Expected O, but got Unknown //IL_07ac: Unknown result type (might be due to invalid IL or missing references) //IL_07bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Component)root).GetComponent<OwnedVisuals>() != (Object)null) { return 0; } var targets = (from r in ((Component)root).GetComponentsInChildren<MeshRenderer>(true) select new { renderer = r, kind = VisualSelection.Classify(PathOf(((Component)r).transform, root)) } into x where x.kind != VisualKind.Original && (jewelry.schemaVersion == 2 || x.kind != VisualKind.Skin) select x).ToArray(); if (targets.Count(x => x.kind == VisualKind.Clothing) != 10 || targets.Count(x => x.kind == VisualKind.Hair) != 5 || (jewelry.schemaVersion == 2 && targets.Count(x => x.kind == VisualKind.Skin) != 15)) { throw new InvalidDataException("Loom renderer layout changed."); } Transform[] parents = jewelry.parts.Select((JewelryPart p) => root.Find(p.parentPath)).ToArray(); if (parents.Any((Transform p) => (Object)(object)p == (Object)null)) { throw new InvalidDataException("Jewelry attachment point missing."); } if (jewelry.schemaVersion == 2 && (from x in targets where x.kind == VisualKind.Clothing select ((Component)x.renderer).transform).ToArray().Any((Transform t) => !parents.Contains(t))) { throw new InvalidDataException("Replacement clothing mesh missing."); } HashSet<Transform> hashSet = new HashSet<Transform>(from x in jewelry.parts.Select((JewelryPart p, int num4) => new { part = p, parent = parents[num4] }) where x.part.replacesParentRenderer select x.parent); if (hashSet.Any((Transform p) => !targets.Any(t => (Object)(object)((Component)t.renderer).transform == (Object)(object)p && t.kind == VisualKind.Skin))) { throw new InvalidDataException("Face renderer missing."); } OwnedVisuals ownedVisuals = ((Component)root).gameObject.AddComponent<OwnedVisuals>(); try { var array = targets; foreach (var anon in array) { ownedVisuals.renderers.Add(anon.renderer); ownedVisuals.originals.Add(((Renderer)anon.renderer).sharedMaterial); ownedVisuals.enabledStates.Add(((Renderer)anon.renderer).enabled); Material val = new Material(((Renderer)anon.renderer).sharedMaterial); ((Object)val).name = "LoomReskin_" + anon.kind; ownedVisuals.assets.Add((Object)(object)val); Color val2 = (Color)((anon.kind == VisualKind.Skin) ? jewelry.skinTint : ((anon.kind == VisualKind.Clothing) ? new Color(2.1f, 0.23f, 0.18f, 0f) : new Color(1.4f, 1.16f, 0.66f, 0f))); val2.a = 0f; if (val.HasProperty("_AlbedoColor")) { val.SetColor("_AlbedoColor", val2); } ((Renderer)anon.renderer).sharedMaterial = val; if (anon.kind == VisualKind.Hair || (jewelry.schemaVersion == 2 && anon.kind == VisualKind.Clothing) || hashSet.Contains(((Component)anon.renderer).transform)) { ((Renderer)anon.renderer).enabled = false; } } VisualMaterial[] obj = ((jewelry.schemaVersion == 2) ? jewelry.materials : new VisualMaterial[4] { new VisualMaterial { name = "Silver", color = new Color(0.72f, 0.78f, 0.83f, 1f), metallic = 0.75f, smoothness = 0.55f }, new VisualMaterial { name = "Hair0", color = new Color(0.22f, 0.19f, 0.095f, 1f) }, new VisualMaterial { name = "Hair1", color = new Color(0.29f, 0.255f, 0.14f, 1f) }, new VisualMaterial { name = "Hair2", color = new Color(0.16f, 0.14f, 0.075f, 1f) } }); Dictionary<string, Material> dictionary = new Dictionary<string, Material>(); VisualMaterial[] array2 = obj; foreach (VisualMaterial visualMaterial in array2) { Material val3 = new Material(((Renderer)targets[0].renderer).sharedMaterial); ownedVisuals.assets.Add((Object)(object)val3); ((Object)val3).name = "LoomReskin_" + visualMaterial.name; string[] array3 = new string[5] { "_AlbedoTexture", "_NormalTexture", "_MetallicTexture", "_SmoothnessTexture", "_EmissionTexture" }; foreach (string text in array3) { if (val3.HasProperty(text)) { val3.SetTexture(text, (Texture)null); } } if (val3.HasProperty("_EmissionColor")) { val3.SetColor("_EmissionColor", Color.black); } array3 = new string[3] { "_NormalStrength", "_OffsetX", "_OffsetY" }; foreach (string text2 in array3) { if (val3.HasProperty(text2)) { val3.SetFloat(text2, 0f); } } array3 = new string[2] { "_TilingX", "_TilingY" }; foreach (string text3 in array3) { if (val3.HasProperty(text3)) { val3.SetFloat(text3, 1f); } } Color color = visualMaterial.color; color.a = 0f; if (val3.HasProperty("_AlbedoColor")) { val3.SetColor("_AlbedoColor", color); } if (val3.HasProperty("_Metallic")) { val3.SetFloat("_Metallic", visualMaterial.metallic); } if (val3.HasProperty("_Smoothness")) { val3.SetFloat("_Smoothness", visualMaterial.smoothness); } if (visualMaterial.texture != null) { if (!val3.HasProperty("_AlbedoTexture")) { throw new InvalidDataException("Game shader has no albedo texture input."); } bool flag = AssetLoader.IsSmoothFaceTexture(visualMaterial.texture); Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, flag, false); ownedVisuals.assets.Add((Object)(object)val4); if (!ImageConversion.LoadImage(val4, File.ReadAllBytes(Path.Combine(assetDirectory, visualMaterial.texture)), false)) { throw new InvalidDataException("Invalid authored visual texture."); } if (flag) { val4.Apply(true, false); } ((Object)val4).name = "LoomReskin_" + visualMaterial.name; ((Texture)val4).filterMode = (FilterMode)(flag ? 2 : 0); ((Texture)val4).wrapMode = (TextureWrapMode)(flag ? 1 : 0); val3.SetTexture("_AlbedoTexture", (Texture)(object)val4); val3.SetTextureScale("_AlbedoTexture", Vector2.one); val3.SetTextureOffset("_AlbedoTexture", Vector2.zero); } dictionary.Add(visualMaterial.name, val3); } int i; for (i = 0; i < jewelry.parts.Length; i++) { JewelryPart jewelryPart = jewelry.parts[i]; GameObject val5 = new GameObject("LoomJewelry_" + jewelryPart.name); ownedVisuals.additions.Add(val5); val5.layer = ((Component)parents[i]).gameObject.layer; val5.transform.SetParent(parents[i], false); Mesh val6 = new Mesh { name = jewelryPart.name }; val6.vertices = jewelryPart.vertices; val6.triangles = jewelryPart.triangles; if (jewelryPart.normals != null) { val6.normals = jewelryPart.normals; } else { val6.RecalculateNormals(); } if (jewelryPart.uv != null) { val6.uv = jewelryPart.uv; } val6.RecalculateBounds(); ownedVisuals.assets.Add((Object)(object)val6); val5.AddComponent<MeshFilter>().sharedMesh = val6; MeshRenderer obj2 = val5.AddComponent<MeshRenderer>(); ((Renderer)obj2).sharedMaterial = dictionary[jewelryPart.material ?? "Silver"]; int num3 = ownedVisuals.renderers.FindIndex((MeshRenderer r) => (Object)(object)((Component)r).transform == (Object)(object)parents[i]); ((Renderer)obj2).enabled = jewelryPart.enabled && (num3 < 0 || (VisualSelection.Classify(jewelryPart.parentPath) != VisualKind.Clothing && !jewelryPart.replacesParentRenderer) || ownedVisuals.enabledStates[num3]); } return targets.Length; } catch { Object.DestroyImmediate((Object)(object)ownedVisuals); throw; } } } internal static class PreviewCapture { internal static void Save(GameObject root, string folder) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) root.transform.position = new Vector3(10000f, 10000f, 10000f); Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 31; } MeshRenderer[] componentsInChildren2 = root.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren2) { if (!Visuals.PathOf(((Component)val).transform, root.transform).StartsWith("Enable/[VISUALS]/Whole mesh CODE ✢/Whole Mesh ANIM ⟺/")) { ((Renderer)val).enabled = false; } } root.SetActive(true); GameObject val2 = new GameObject("Loom verification camera"); GameObject val3 = new GameObject("Loom verification light"); RenderTexture val4 = new RenderTexture(720, 960, 24); try { Light obj = val3.AddComponent<Light>(); obj.type = (LightType)1; obj.intensity = 1.3f; obj.cullingMask = int.MinValue; ((Component)obj).transform.rotation = Quaternion.Euler(25f, 155f, 0f); Camera obj2 = val2.AddComponent<Camera>(); ((Behaviour)obj2).enabled = false; obj2.orthographic = true; obj2.orthographicSize = 2.08f; obj2.aspect = 0.75f; obj2.cullingMask = int.MinValue; obj2.useOcclusionCulling = false; obj2.clearFlags = (CameraClearFlags)2; obj2.backgroundColor = new Color(0.16f, 0.17f, 0.19f, 1f); obj2.nearClipPlane = 0.1f; obj2.farClipPlane = 30f; obj2.targetTexture = val4; Directory.CreateDirectory(folder); Capture(obj2, root, new Vector3(0f, 1.9f, 8f), val4, Path.Combine(folder, "loom-runtime-front.png")); Capture(obj2, root, new Vector3(-4f, 1.9f, 6f), val4, Path.Combine(folder, "loom-runtime-three-quarter.png")); } finally { root.SetActive(false); Object.Destroy((Object)(object)val2); Object.Destroy((Object)(object)val3); val4.Release(); Object.Destroy((Object)(object)val4); } } private static void Capture(Camera camera, GameObject root, Vector3 offset, RenderTexture target, string file) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) ((Component)camera).transform.position = root.transform.position + offset; ((Component)camera).transform.LookAt(root.transform.position + new Vector3(0f, 1.9f, 0f)); camera.Render(); RenderTexture active = RenderTexture.active; RenderTexture.active = target; Texture2D val = new Texture2D(((Texture)target).width, ((Texture)target).height, (TextureFormat)3, false); try { val.ReadPixels(new Rect(0f, 0f, (float)((Texture)target).width, (float)((Texture)target).height), 0, 0); val.Apply(); File.WriteAllBytes(file, ImageConversion.EncodeToPNG(val)); } finally { RenderTexture.active = active; Object.Destroy((Object)(object)val); } } } [Serializable] public sealed class JewelryAsset { public int schemaVersion; public JewelryPart[] parts; public VisualMaterial[] materials; public Color skinTint; } [Serializable] public sealed class JewelryPart { public string name; public string material; public string parentPath; public bool enabled = true; public bool replacesParentRenderer; public Vector3[] vertices; public int[] triangles; public Vector3[] normals; public Vector2[] uv; } [Serializable] public sealed class VisualMaterial { public string name; public Color color; public float metallic; public float smoothness; public string texture; } public static class AssetLoader { internal static bool IsSmoothFaceTexture(string texture) { if (!(texture == "delloom-face.png")) { return texture == "rodin-face.png"; } return true; } private static bool Finite(float f) { if (!float.IsNaN(f)) { return !float.IsInfinity(f); } return false; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (Finite(v.x) && Finite(v.y)) { return Finite(v.z); } return false; } private static bool Unit(float f) { if (Finite(f) && f >= 0f) { return f <= 1f; } return false; } private static bool ValidColor(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (Unit(c.r) && Unit(c.g) && Unit(c.b)) { return Unit(c.a); } return false; } public static JewelryAsset Parse(string json) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) JewelryAsset jewelryAsset = JsonConvert.DeserializeObject<JewelryAsset>(json); if (jewelryAsset == null || (jewelryAsset.schemaVersion != 1 && jewelryAsset.schemaVersion != 2) || jewelryAsset.parts == null || jewelryAsset.parts.Length == 0) { throw new InvalidDataException("Unsupported or empty visual asset."); } HashSet<string> hashSet = new HashSet<string>(); Dictionary<string, VisualMaterial> dictionary = new Dictionary<string, VisualMaterial>(); if (jewelryAsset.schemaVersion == 2) { if (jewelryAsset.materials == null || jewelryAsset.materials.Length == 0 || !ValidColor(jewelryAsset.skinTint)) { throw new InvalidDataException("Missing visual palette."); } VisualMaterial[] materials = jewelryAsset.materials; foreach (VisualMaterial visualMaterial in materials) { if (visualMaterial == null || string.IsNullOrEmpty(visualMaterial.name) || dictionary.ContainsKey(visualMaterial.name) || !ValidColor(visualMaterial.color) || !Unit(visualMaterial.metallic) || !Unit(visualMaterial.smoothness)) { throw new InvalidDataException("Invalid visual material."); } if (visualMaterial.texture != null && visualMaterial.texture != "crimson-fabric.png" && visualMaterial.texture != "aged-bone.png" && visualMaterial.texture != "ochre-hair.png" && !IsSmoothFaceTexture(visualMaterial.texture)) { throw new InvalidDataException("Unsupported visual texture path."); } dictionary.Add(visualMaterial.name, visualMaterial); } } JewelryPart[] parts = jewelryAsset.parts; foreach (JewelryPart p in parts) { if (p == null || string.IsNullOrEmpty(p.name) || !hashSet.Add(p.name) || string.IsNullOrEmpty(p.parentPath) || !p.parentPath.StartsWith("Enable/[VISUALS]/Whole mesh CODE ✢/Whole Mesh ANIM ⟺/", StringComparison.Ordinal)) { throw new InvalidDataException("Invalid visual identity or parent path."); } if (p.vertices == null || p.vertices.Length < 3 || p.vertices.Length > 65535 || p.vertices.Any((Vector3 v) => !Finite(v)) || p.triangles == null || p.triangles.Length == 0 || p.triangles.Length % 3 != 0 || p.triangles.Any((int num) => num < 0 || num >= p.vertices.Length)) { throw new InvalidDataException("Invalid visual mesh."); } if (p.replacesParentRenderer && (jewelryAsset.schemaVersion != 2 || !p.enabled || !VisualSelection.CanReplaceFace(p.parentPath))) { throw new InvalidDataException("Invalid face replacement target."); } if (jewelryAsset.schemaVersion == 2) { if (p.material == null || !dictionary.ContainsKey(p.material)) { throw new InvalidDataException("Unknown visual material."); } if (p.normals == null || p.normals.Length != p.vertices.Length || p.normals.Any((Vector3 n) => !Finite(n) || n.x * n.x + n.y * n.y + n.z * n.z < 0.5f)) { throw new InvalidDataException("Invalid authored normals."); } if (p.uv != null && (p.uv.Length != p.vertices.Length || p.uv.Any((Vector2 v) => !Finite(v.x) || !Finite(v.y)))) { throw new InvalidDataException("Invalid texture coordinates."); } if (dictionary[p.material].texture != null && p.uv == null) { throw new InvalidDataException("Textured mesh has no UVs."); } } else if (p.material != "Silver" && p.material != "Hair0" && p.material != "Hair1" && p.material != "Hair2") { throw new InvalidDataException("Unknown legacy material."); } } return jewelryAsset; } } public enum VisualKind { Original, Clothing, Hair, Skin } public static class VisualSelection { public const string VisualRoot = "Enable/[VISUALS]/Whole mesh CODE ✢/Whole Mesh ANIM ⟺/"; public static bool CanReplaceFace(string path) { if (Classify(path) == VisualKind.Skin) { if (!path.EndsWith("/Top head (mesh)", StringComparison.Ordinal)) { return path.EndsWith("/Jaw (mesh)", StringComparison.Ordinal); } return true; } return false; } public static VisualKind Classify(string path) { if (path == null || !path.StartsWith("Enable/[VISUALS]/Whole mesh CODE ✢/Whole Mesh ANIM ⟺/", StringComparison.Ordinal)) { return VisualKind.Original; } string text = path.Substring(path.LastIndexOf('/') + 1); switch (text) { case "Dress (mesh)": case "Torso (mesh)": case "Upper arm (mesh)": case "Lower arm (mesh)": return VisualKind.Clothing; default: if (path.Contains("/Head ANIM ⟺/Hair/")) { switch (text) { case "Back Hair": case "Side hair 1": case "Side Hair 2": case "Bangs": case "Back hair": return VisualKind.Hair; } } if ((path.Contains("/Head ANIM ⟺/") && (text == "Top head (mesh)" || text == "Jaw (mesh)")) || (path.Contains("/Neck ANIM ⟺/") && text == "Neck (mesh)")) { return VisualKind.Skin; } if (path.StartsWith("Enable/[VISUALS]/Whole mesh CODE ✢/Whole Mesh ANIM ⟺/Hand RIGHT/", StringComparison.Ordinal) || path.StartsWith("Enable/[VISUALS]/Whole mesh CODE ✢/Whole Mesh ANIM ⟺/Hand LEFT/Hand LEFT/", StringComparison.Ordinal)) { switch (text) { case "palm (mesh)": case "index finger": case "middle finger": case "ring finger": case "pinkie": case "thumb": return VisualKind.Skin; } } return VisualKind.Original; } } } }