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 OdinsBelt v0.2.5
BepInEx/plugins/OdinsBelt/OdinsBelt.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Concurrent; 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 System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using SailingProgression; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("OdinsBelt")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.5.0")] [assembly: AssemblyInformationalVersion("0.2.5")] [assembly: AssemblyProduct("OdinsBelt")] [assembly: AssemblyTitle("OdinsBelt")] [assembly: AssemblyVersion("0.2.5.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 SailingProgression { public static class TailwindVisuals { private static Material bronze; private static Material leather; private static Material dark; private static Material wind; public static void Apply(GameObject prefab, bool charm) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) SharedData shared = prefab.GetComponent<ItemDrop>().m_itemData.m_shared; using (Stream stream = typeof(TailwindVisuals).Assembly.GetManifestResourceStream("TailwindGear." + (charm ? "charm" : "belt") + ".png")) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2); AssetUtils.LoadImage(val, memoryStream.ToArray()); shared.m_icons = (Sprite[])(object)new Sprite[1] { Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)) }; } Materials(prefab); Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } LODGroup[] componentsInChildren2 = prefab.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } Transform val2 = prefab.transform.Find("attach"); if (Object.op_Implicit((Object)(object)val2)) { Object.DestroyImmediate((Object)(object)((Component)val2).gameObject); } Transform transform = new GameObject("attach").transform; transform.SetParent(prefab.transform, false); if (charm) { Charm(transform); } else { Belt(transform); } Bounds val3 = default(Bounds); ((Bounds)(ref val3))..ctor(Vector3.zero, Vector3.zero); bool flag = true; MeshFilter[] componentsInChildren4 = ((Component)transform).GetComponentsInChildren<MeshFilter>(); foreach (MeshFilter val4 in componentsInChildren4) { Vector3[] vertices = val4.sharedMesh.vertices; foreach (Vector3 val5 in vertices) { Vector3 val6 = prefab.transform.InverseTransformPoint(((Component)val4).transform.TransformPoint(val5)); if (flag) { ((Bounds)(ref val3))..ctor(val6, Vector3.zero); flag = false; } else { ((Bounds)(ref val3)).Encapsulate(val6); } } } BoxCollider obj = prefab.AddComponent<BoxCollider>(); obj.center = ((Bounds)(ref val3)).center; obj.size = ((Bounds)(ref val3)).size + Vector3.one * 0.008f; shared.m_weight = (charm ? 0.5f : 1f); } private static void Materials(GameObject prefab) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)bronze)) { return; } Material val = null; Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; foreach (Material val2 in sharedMaterials) { if (Object.op_Implicit((Object)(object)val2)) { val = val2; break; } } } if (!Object.op_Implicit((Object)(object)val)) { Material[] sharedMaterials = Resources.FindObjectsOfTypeAll<Material>(); foreach (Material val3 in sharedMaterials) { if (Object.op_Implicit((Object)(object)val3)) { val = val3; break; } } } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("No native item material available."); } bronze = Material(val, new Color(0.61f, 0.4f, 0.15f), 0.65f); leather = Material(val, new Color(0.22f, 0.105f, 0.045f), 0f); dark = Material(val, new Color(0.13f, 0.14f, 0.12f), 0.3f); wind = Material(val, new Color(0.12f, 0.78f, 0.8f), 0.25f); wind.EnableKeyword("_EMISSION"); wind.SetColor("_EmissionColor", new Color(0.035f, 0.35f, 0.4f)); } private static Material Material(Material source, Color color, float metal) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_0018: 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_0035: Expected O, but got Unknown Material val = new Material(source) { mainTexture = (Texture)(object)Texture2D.whiteTexture, color = color }; val.SetFloat("_Metallic", metal); val.SetFloat("_Glossiness", 0.3f); return val; } private static GameObject MeshObject(Transform parent, string name, Vector3[] vertices, int[] triangles, Material material) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); Mesh val2 = new Mesh { name = name }; val2.vertices = vertices; val2.triangles = triangles; val2.RecalculateNormals(); val2.RecalculateBounds(); val.AddComponent<MeshFilter>().sharedMesh = val2; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material; return val; } private static GameObject Ring(Transform parent, string name, float radius, float width, float depth, Material material, int segments = 32) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[segments * 4]; List<int> list = new List<int>(); Vector2 val = default(Vector2); for (int i = 0; i < segments; i++) { float num = (float)i * (float)Math.PI * 2f / (float)segments; ((Vector2)(ref val))..ctor(Mathf.Sin(num), Mathf.Cos(num)); array[i * 4] = new Vector3(val.x * (radius - width / 2f), val.y * (radius - width / 2f), (0f - depth) / 2f); array[i * 4 + 1] = new Vector3(val.x * (radius + width / 2f), val.y * (radius + width / 2f), (0f - depth) / 2f); array[i * 4 + 2] = new Vector3(val.x * (radius - width / 2f), val.y * (radius - width / 2f), depth / 2f); array[i * 4 + 3] = new Vector3(val.x * (radius + width / 2f), val.y * (radius + width / 2f), depth / 2f); int num2 = (i + 1) % segments * 4; int num3 = i * 4; Quad(list, num3, num3 + 1, num2 + 1, num2); Quad(list, num3 + 2, num2 + 2, num2 + 3, num3 + 3); Quad(list, num3, num2, num2 + 2, num3 + 2); Quad(list, num3 + 1, num3 + 3, num2 + 3, num2 + 1); } return MeshObject(parent, name, array, list.ToArray(), material); } private static void Quad(List<int> t, int a, int b, int c, int d) { t.AddRange(new int[6] { a, b, c, a, c, d }); } private static void Bar(Transform p, string name, Vector3 a, Vector3 b, float width, float thickness, Material m) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) //IL_006c: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) Vector3 val = b - a; Vector3 val2 = new Vector3(0f - val.y, val.x, 0f); Vector3 val3 = ((Vector3)(ref val2)).normalized * width / 2f; Vector3[] vertices = (Vector3[])(object)new Vector3[8] { a + val3, a - val3, b - val3, b + val3, a + val3 + Vector3.forward * thickness, a - val3 + Vector3.forward * thickness, b - val3 + Vector3.forward * thickness, b + val3 + Vector3.forward * thickness }; List<int> list = new List<int>(); Quad(list, 0, 3, 2, 1); Quad(list, 4, 5, 6, 7); Quad(list, 0, 1, 5, 4); Quad(list, 1, 2, 6, 5); Quad(list, 2, 3, 7, 6); Quad(list, 3, 0, 4, 7); MeshObject(p, name, vertices, list.ToArray(), m); } private static void Gem(Transform p, string name, Vector3 center, float radius, Material m) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = (Vector3[])(object)new Vector3[6] { center + Vector3.forward * radius, center - Vector3.forward * radius, center + Vector3.up * radius, center - Vector3.up * radius, center + Vector3.right * radius, center - Vector3.right * radius }; MeshObject(p, name, vertices, new int[24] { 0, 4, 2, 0, 3, 4, 0, 5, 3, 0, 2, 5, 1, 2, 4, 1, 4, 3, 1, 3, 5, 1, 5, 2 }, m); } private static void Ship(Transform p, float scale, float y, float z) { //IL_002a: 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_006d: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) Bar(p, "Dragonship keel", V(-0.055f, -0.028f), V(0.055f, -0.028f), 0.01f * scale, 0.006f, bronze); Bar(p, "Raised prow", V(-0.055f, -0.028f), V(-0.07f, 0.005f), 0.012f * scale, 0.006f, bronze); Bar(p, "Raised stern", V(0.055f, -0.028f), V(0.064f, -0.003f), 0.009f * scale, 0.006f, bronze); Bar(p, "Mast", V(0f, -0.022f), V(0f, 0.052f), 0.009f * scale, 0.008f, bronze); MeshObject(p, "Curved sail", (Vector3[])(object)new Vector3[4] { V(0.006f, 0.045f), V(0.047f, 0.036f), V(0.054f, 0.001f), V(0.007f, 0.002f) }, new int[12] { 0, 1, 2, 0, 2, 3, 2, 1, 0, 3, 2, 0 }, bronze); Vector3 V(float x, float yy) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x * scale, yy * scale + y, z); } } private static void Wind(Transform p, float radius, float z) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 3; i++) { Vector3[] array = (Vector3[])(object)new Vector3[14]; for (int j = 0; j < array.Length; j++) { float num = (float)j / (float)(array.Length - 1) * 1.7f + (float)i * 2.1f; float num2 = radius * (0.8f + 0.13f * Mathf.Sin((float)j * 0.8f)); array[j] = new Vector3(Mathf.Sin(num) * num2, Mathf.Cos(num) * num2, z); } for (int k = 1; k < array.Length; k++) { Bar(p, "Turquoise wind", array[k - 1], array[k], 0.004f, 0.002f, wind); } } } private static void Charm(Transform p) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_018b: Unknown result type (might be due to invalid IL or missing references) Ring(p, "Bronze pendant", 0.095f, 0.016f, 0.013f, bronze); Ring(p, "Dark inner band", 0.078f, 0.006f, 0.01f, dark); Ring(p, "Suspension ring", 0.016f, 0.007f, 0.012f, bronze, 12).transform.localPosition = new Vector3(0f, 0.115f, 0f); Bar(p, "Leather cord left", new Vector3(-0.025f, 0.127f, 0f), new Vector3(-0.065f, 0.23f, 0f), 0.009f, 0.007f, leather); Bar(p, "Leather cord right", new Vector3(0.025f, 0.127f, 0f), new Vector3(0.065f, 0.23f, 0f), 0.009f, 0.007f, leather); Gem(p, "Wind stone", new Vector3(0f, 0.025f, -0.012f), 0.023f, wind); Ship(p, 1f, -0.039f, -0.015f); Wind(p, 0.069f, -0.023f); for (int i = 0; i < 12; i++) { float num = (float)i * (float)Math.PI / 6f; Gem(p, "Bronze rivet", new Vector3(Mathf.Sin(num) * 0.096f, Mathf.Cos(num) * 0.096f, -0.012f), 0.005f, bronze); } } private static void Belt(Transform p) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) Ring(p, "Leather belt", 0.16f, 0.012f, 0.067f, leather, 40).transform.localRotation = Quaternion.Euler(90f, 0f, 0f); Transform transform = new GameObject("Ship buckle").transform; transform.SetParent(p, false); transform.localPosition = new Vector3(0f, 0f, -0.168f); Ring(transform, "Bronze buckle rim", 0.063f, 0.012f, 0.014f, bronze, 24); Ring(transform, "Buckle inner rim", 0.049f, 0.006f, 0.009f, dark, 24); Ship(transform, 0.75f, 0.006f, -0.011f); Wind(transform, 0.052f, -0.021f); Gem(transform, "Turquoise buckle stone", new Vector3(0f, -0.046f, -0.015f), 0.012f, wind); Vector3 localPosition = default(Vector3); for (int i = 0; i < 20; i++) { float num = (float)i * (float)Math.PI / 10f; ((Vector3)(ref localPosition))..ctor(Mathf.Sin(num) * 0.168f, 0f, Mathf.Cos(num) * 0.168f); Transform transform2 = new GameObject("Bronze belt detail").transform; transform2.SetParent(p, false); transform2.localPosition = localPosition; transform2.localRotation = Quaternion.Euler(0f, num * 57.29578f, 0f); Bar(transform2, "Stamped knot", new Vector3(-0.008f, -0.024f, 0f), new Vector3(0.008f, 0.024f, 0f), 0.003f, 0.003f, bronze); Bar(transform2, "Stamped knot", new Vector3(0.008f, -0.024f, 0f), new Vector3(-0.008f, 0.024f, 0f), 0.003f, 0.003f, bronze); } } public static GameObject CreateLeatherBand(Transform parent, float radius, float thickness, float height, Material material) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Ring(parent, "Leather belt", radius, thickness, height, material, 40); obj.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); return obj; } } } namespace UtilityBelt { internal static class BeltDragAndDrop { [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] private static class DropIntoInventory { private static bool Prefix(InventoryGrid grid, Vector2i pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return DropTo(grid, pos); } } [HarmonyPatch(typeof(InventoryGui), "OnReleasedItem")] private static class Release { private static bool Prefix(InventoryGrid grid, Vector2i pos) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!Holding) { return true; } if (!Object.op_Implicit((Object)(object)grid)) { Cancel(); return false; } return DropTo(grid, pos); } } [HarmonyPatch(typeof(InventoryGui), "OnDropOutside")] private static class PreventPreviewWorldDrop { private static bool Prefix() { if (!Holding) { return true; } Cancel(); return false; } } [HarmonyPatch(typeof(InventoryGui), "SetupDragItem")] private static class ResetCursor { private static void Postfix(InventoryGui __instance, ItemData item) { if (item == null) { origin = -1; } else if (BeltUI.Open) { object? value = AccessTools.Field(typeof(InventoryGui), "m_dragGo").GetValue(__instance); GameObject val = (GameObject)((value is GameObject) ? value : null); if (Object.op_Implicit((Object)(object)val)) { Canvas obj = val.GetComponent<Canvas>() ?? val.AddComponent<Canvas>(); obj.overrideSorting = true; obj.sortingOrder = GUIManager.CustomGUIFront.GetComponent<Canvas>().sortingOrder + 1; (val.GetComponent<CanvasGroup>() ?? val.AddComponent<CanvasGroup>()).blocksRaycasts = false; } } } } private static int origin = -1; private static int destinationSlot = -1; private static long revision; private static Vector2i destination; internal static bool Holding => origin >= 0; internal static int Origin => origin; internal static bool Begin(int slot) { Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; BeltInventory beltInventory = (Object.op_Implicit((Object)(object)localPlayer) ? BeltNetwork.Selected(localPlayer) : null); if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)instance) || !BeltUI.Open || BeltNetwork.Busy || Holding || beltInventory?.Get(slot) == null) { return false; } if (AccessTools.Field(typeof(InventoryGui), "m_dragItem").GetValue(instance) != null) { return false; } origin = slot; revision = beltInventory.Revision; ItemData val = beltInventory.Get(slot).Clone(); val.m_stack = 1; AccessTools.Method(typeof(InventoryGui), "SetupDragItem", (Type[])null, (Type[])null).Invoke(instance, new object[3] { val, ((Humanoid)localPlayer).GetInventory(), 1 }); return true; } internal static void Cancel(bool clearDestination = true) { bool holding = Holding; origin = -1; if (clearDestination) { destinationSlot = -1; } if (holding && Object.op_Implicit((Object)(object)InventoryGui.instance)) { AccessTools.Method(typeof(InventoryGui), "SetupDragItem", (Type[])null, (Type[])null).Invoke(InventoryGui.instance, new object[3] { null, null, 1 }); } } internal static void End(PointerEventData pointer) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (Holding) { RaycastResult pointerCurrentRaycast = pointer.pointerCurrentRaycast; GameObject gameObject = ((RaycastResult)(ref pointerCurrentRaycast)).gameObject; InventoryElement val = (Object.op_Implicit((Object)(object)gameObject) ? gameObject.GetComponentInParent<InventoryElement>() : null); InventoryGrid val2 = (Object.op_Implicit((Object)(object)gameObject) ? gameObject.GetComponentInParent<InventoryGrid>() : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { DropTo(val2, val.Position); } if (Holding) { Cancel(); } } } private static bool DropTo(InventoryGrid grid, Vector2i pos) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!Holding) { return true; } Player localPlayer = Player.m_localPlayer; BeltInventory beltInventory = (Object.op_Implicit((Object)(object)localPlayer) ? BeltNetwork.Selected(localPlayer) : null); if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)grid) || grid.GetInventory() != ((Humanoid)localPlayer).GetInventory()) { BeltNetwork.LastMessage = "Drag the item to your inventory."; return false; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (pos.x < 0 || pos.y < 0 || pos.x >= inventory.GetWidth() || pos.y >= inventory.GetHeight() || inventory.GetItemAt(pos.x, pos.y) != null) { BeltNetwork.LastMessage = "Drop it into an empty inventory slot."; return false; } if (beltInventory == null || beltInventory.Revision != revision || beltInventory.Get(origin) == null) { Cancel(); BeltNetwork.LastMessage = "The belt changed. Pick the item up again."; return false; } int slot = (destinationSlot = origin); destination = pos; if (BeltNetwork.Request(2, slot)) { Cancel(clearDestination: false); } else { destinationSlot = -1; } return false; } internal static void TransferFinished(int action, int slot, ItemData? delivered) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (action != 2 || destinationSlot != slot) { return; } destinationSlot = -1; Player localPlayer = Player.m_localPlayer; if (delivered != null && Object.op_Implicit((Object)(object)localPlayer)) { Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory.GetItemAt(destination.x, destination.y) == null) { delivered.m_gridPos = destination; AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null).Invoke(inventory, new object[2] { true, false }); } } } } public sealed class BeltInventory { public const int UtilityCount = 10; public const int KeyCount = 10; public const int KeyStart = 11; public const int VisibleCapacity = 21; public const int Capacity = 43; public readonly Inventory Inventory = new Inventory("Utility Belt", (Sprite)null, 8, 6); public long Revision; public bool LanternOn = true; public int ActiveSlots = 2046; public string LastTransaction = ""; public string LastReceipt = ""; public bool NativeEquipped; public int OverflowCount => Inventory.GetAllItems().Count((ItemData i) => i.m_gridPos.x + i.m_gridPos.y * 8 >= 21); public bool Equipped => NativeEquipped; public bool IsActive(int slot) { if (slot >= 1 && slot <= 10) { return (ActiveSlots & (1 << slot)) != 0; } return false; } public int FindUtility(string prefab, bool activeOnly = false) { return Enumerable.Range(1, 10).FirstOrDefault(delegate(int s) { ItemData val = Get(s); return val != null && Prefab(val) == prefab && (!activeOnly || IsActive(s)); }); } public ItemData? Utility(string prefab) { int num = FindUtility(prefab); if (num != 0) { return Get(num); } return null; } public static bool IsUtility(ItemData item) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 if (!Keyring.IsKey(Prefab(item)) && (Prefab(item) == "Lantern" || (int)item.m_shared.m_itemType == 18)) { return Prefab(item) != "OdinsBelt"; } return false; } public ItemData? Get(int slot) { return Inventory.GetItemAt(slot % 8, slot / 8); } public static string Prefab(ItemData item) { if (!Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ""; } return ((Object)item.m_dropPrefab).name; } public static bool ValidSlot(int slot, ItemData item, bool allowSavedTrinket = false) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 if (slot < 0 || slot >= 43 || item.m_stack != 1 || item.m_quality < 1 || item.m_quality > Math.Max(1, item.m_shared.m_maxQuality)) { return false; } if (slot != 0) { if (slot >= 11) { return Keyring.IsKey(Prefab(item)); } if (!IsUtility(item)) { if (allowSavedTrinket) { return (int)item.m_shared.m_itemType == 24; } return false; } return true; } return Prefab(item) == "OdinsBelt"; } public bool Put(int slot, ItemData item) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!ValidSlot(slot, item) || Get(slot) != null) { return false; } item.m_equipped = false; return Inventory.AddItem(item, new Vector2i(slot % 8, slot / 8)); } public string Encode() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); Inventory.Save(val); ZPackage val2 = new ZPackage(); val2.Write(4); val2.Write(Revision); val2.Write(LanternOn); val2.Write(LastTransaction); val2.Write(LastReceipt); val2.Write(ActiveSlots); val2.Write(NativeEquipped); val2.Write(Convert.ToBase64String(val.GetArray())); return Convert.ToBase64String(val2.GetArray()); } public static BeltInventory Decode(string encoded) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) BeltInventory beltInventory = new BeltInventory(); if (string.IsNullOrEmpty(encoded)) { return beltInventory; } if (encoded.Length > 262144) { throw new ArgumentException("Belt save exceeds limit"); } ZPackage val = new ZPackage(Convert.FromBase64String(encoded)); int num = val.ReadInt(); if (num < 1 || num > 4) { throw new ArgumentException("Unsupported belt save version"); } beltInventory.Revision = val.ReadLong(); beltInventory.LanternOn = val.ReadBool(); beltInventory.LastTransaction = val.ReadString(); beltInventory.LastReceipt = val.ReadString(); if (num >= 2) { beltInventory.ActiveSlots = val.ReadInt() & 0x7FE; } if (num < 4) { beltInventory.ActiveSlots |= 2016; if (!beltInventory.LanternOn) { beltInventory.ActiveSlots &= -17; } } if (num >= 3) { beltInventory.NativeEquipped = val.ReadBool(); } beltInventory.Inventory.Load(new ZPackage(Convert.FromBase64String(val.ReadString()))); if (num < 4) { ItemData[] array = beltInventory.Inventory.GetAllItems().ToArray(); beltInventory.Inventory.RemoveAll(); ItemData[] array2 = array; foreach (ItemData val2 in array2) { int num2 = val2.m_gridPos.x + val2.m_gridPos.y * 8; if (num2 >= 5) { num2 += 6; } if (!ValidSlot(num2, val2, allowSavedTrinket: true) || !beltInventory.Inventory.AddItem(val2, new Vector2i(num2 % 8, num2 / 8))) { throw new ArgumentException("Invalid legacy belt item"); } } } foreach (ItemData allItem in beltInventory.Inventory.GetAllItems()) { if (!ValidSlot(allItem.m_gridPos.x + allItem.m_gridPos.y * 8, allItem, allowSavedTrinket: true)) { throw new ArgumentException("Invalid belt item or slot"); } } return beltInventory; } internal void PromoteSavedKeys() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) ItemData[] array = (from i in Inventory.GetAllItems() where i.m_gridPos.x + i.m_gridPos.y * 8 >= 21 select i).ToArray(); foreach (ItemData val in array) { int num2 = Enumerable.Range(11, 10).FirstOrDefault((int s) => Get(s) == null); if (num2 != 0) { Inventory.RemoveItem(val); Inventory.AddItem(val, new Vector2i(num2 % 8, num2 / 8)); continue; } break; } } public static string PackItem(ItemData item) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown Inventory val = new Inventory("Transfer", (Sprite)null, 1, 1); ItemData val2 = item.Clone(); val2.m_stack = 1; val2.m_equipped = false; val.AddItem(val2); ZPackage val3 = new ZPackage(); val.Save(val3); return Convert.ToBase64String(val3.GetArray()); } public static ItemData UnpackItem(string value) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if (value.Length > 65536) { throw new ArgumentException("Item exceeds limit"); } Inventory val = new Inventory("Transfer", (Sprite)null, 1, 1); val.Load(new ZPackage(Convert.FromBase64String(value))); if (val.GetAllItems().Count != 1 || val.GetAllItems()[0].m_stack != 1) { throw new ArgumentException("Invalid item transfer"); } return val.GetAllItems()[0]; } } public static class BeltNetwork { private sealed class Pending { public int Action; public int Slot; public long Revision; public string BeltId = ""; public string Transaction = ""; public string Payload = ""; public string Receipt = ""; public bool Acknowledged; public string Encode() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(Action); val.Write(Slot); val.Write(Revision); val.Write(Transaction); val.Write(Payload); val.Write(Receipt); val.Write(Acknowledged); val.Write(BeltId); return Convert.ToBase64String(val.GetArray()); } public static Pending Decode(string value) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown ZPackage val = new ZPackage(Convert.FromBase64String(value)); return new Pending { Action = val.ReadInt(), Slot = val.ReadInt(), Revision = val.ReadLong(), Transaction = val.ReadString(), Payload = val.ReadString(), Receipt = val.ReadString(), Acknowledged = val.ReadBool(), BeltId = ((val.GetPos() < val.GetArray().Length) ? val.ReadString() : "") }; } } [HarmonyPatch(typeof(Game), "Shutdown")] private static class LogoutPolicy { private static void Prefix() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) Persistence.Flush(); if (Plugin.KeepOnLogout.Value) { return; } if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer() && Object.op_Implicit((Object)(object)ZNetScene.instance)) { KeyValuePair<long, (long, ZDOID, Vector3)>[] array = Online.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<long, (long, ZDOID, Vector3)> keyValuePair = array[i]; DropContents(keyValuePair.Key, keyValuePair.Value.Item3); } } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { localPlayer.m_customData["branchofyore.odinsbelt.state"] = new BeltInventory().Encode(); } Persistence.Flush(); } } private const string RequestRpc = "branchofyore.odinsbelt.request"; private const string ReplyRpc = "branchofyore.odinsbelt.reply"; private const string SnapshotRpc = "branchofyore.odinsbelt.snapshot"; public const string SaveKey = "branchofyore.odinsbelt.state"; public const string PendingKey = "branchofyore.odinsbelt.pending"; private static readonly Dictionary<long, BeltInventory> ServerStates = new Dictionary<long, BeltInventory>(); private static readonly Dictionary<long, BeltInventory> ClientStates = new Dictionary<long, BeltInventory>(); private static readonly Dictionary<long, (long peer, ZDOID player, Vector3 position)> Online = new Dictionary<long, (long, ZDOID, Vector3)>(); private static readonly HashSet<long> Dead = new HashSet<long>(); private static readonly HashSet<long> Committing = new HashSet<long>(); private static readonly Dictionary<long, string> RecordOwners = new Dictionary<long, string>(); private static readonly Dictionary<long, string> SelectedIds = new Dictionary<long, string>(); private static readonly Dictionary<long, string> ServerSelectedIds = new Dictionary<long, string>(); private static readonly Dictionary<long, BeltInventory> EquippedStates = new Dictionary<long, BeltInventory>(); private static readonly Dictionary<string, BeltInventory> Records = new Dictionary<string, BeltInventory>(); private static readonly Dictionary<long, HashSet<string>> HeldIds = new Dictionary<long, HashSet<string>>(); private static readonly Dictionary<ItemData, (string blob, BeltInventory state)> DecodedItems = new Dictionary<ItemData, (string, BeltInventory)>(); private static ItemData? selectedItem; private static string synchronizedId = ""; private static string synchronizedEquipped = ""; private static string synchronizedHeld = ""; public const string ItemIdKey = "branchofyore.odinsbelt.belt-id"; public const string ItemStateKey = "branchofyore.odinsbelt.contents"; private static ZRoutedRpc? registered; private static long world; private static float nextSync; private static float nextRetry; private static Pending? pending; private static long localId; private static bool awaitingSync; private static string syncTransaction = ""; public static string LastMessage = ""; public static bool Busy => pending != null; public static bool Ready { get { if (!awaitingSync && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ItemData val = CurrentItem(Player.m_localPlayer); if (val != null && SelectedIds.TryGetValue(Player.m_localPlayer.GetPlayerID(), out string value)) { return value == Identity(val); } } return false; } } public static long ServerId { get { if (ZRoutedRpc.instance != null) { return (long)AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null).Invoke(ZRoutedRpc.instance, null); } return 0L; } } private static BeltInventory Contents(ItemData item) { string value; string text = (item.m_customData.TryGetValue("branchofyore.odinsbelt.contents", out value) ? value : ""); if (!DecodedItems.TryGetValue(item, out (string, BeltInventory) value2) || value2.Item1 != text) { value2 = (text, BeltInventory.Decode(text)); DecodedItems[item] = value2; } value2.Item2.NativeEquipped = item.m_equipped; return value2.Item2; } private static string Owned(Player p) { return string.Join(",", from id in (from i in ((Humanoid)p).GetInventory().GetAllItems() where BeltInventory.Prefab(i) == "OdinsBelt" select i).Select(Identity).Distinct() orderby id select id); } public static string Identity(ItemData item) { if (!item.m_customData.TryGetValue("branchofyore.odinsbelt.belt-id", out var value) || !Guid.TryParseExact(value, "N", out var _)) { value = (item.m_customData["branchofyore.odinsbelt.belt-id"] = Guid.NewGuid().ToString("N")); } return value; } private static ItemData? EquippedItem(Player p) { return ((IEnumerable<ItemData>)((Humanoid)p).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => BeltInventory.Prefab(i) == "OdinsBelt" && i.m_equipped)); } private static ItemData? CurrentItem(Player p) { if (BeltUI.Open && selectedItem != null && ((Humanoid)p).GetInventory().ContainsItem(selectedItem)) { return selectedItem; } ItemData? obj = EquippedItem(p); if (obj == null) { if (selectedItem == null || !((Humanoid)p).GetInventory().ContainsItem(selectedItem)) { return ((IEnumerable<ItemData>)((Humanoid)p).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => BeltInventory.Prefab(i) == "OdinsBelt")); } obj = selectedItem; } return obj; } public static void SynchronizeSelected() { if (registered != null && Object.op_Implicit((Object)(object)Player.m_localPlayer) && !Busy && !Ready) { SendSync(Player.m_localPlayer); } } public static bool Select(ItemData item) { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || Busy || !((Humanoid)localPlayer).GetInventory().ContainsItem(item) || BeltInventory.Prefab(item) != "OdinsBelt") { return false; } selectedItem = item; Identity(item); synchronizedId = ""; awaitingSync = false; return true; } public static BeltInventory? Selected(Player p) { ItemData val = CurrentItem(p); if (val == null) { return null; } string text = Identity(val); if (SelectedIds.TryGetValue(p.GetPlayerID(), out string value) && value == text && ClientStates.TryGetValue(p.GetPlayerID(), out BeltInventory value2)) { value2.NativeEquipped = val.m_equipped; return value2; } return Contents(val); } public static BeltInventory? For(Player player) { if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { ItemData val = EquippedItem(player) ?? CurrentItem(player); if (val == null) { return new BeltInventory(); } return Contents(val); } if (!EquippedStates.TryGetValue(player.GetPlayerID(), out BeltInventory value)) { return null; } return value; } public static void Update() { if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZRoutedRpc.instance == null || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } if (registered != ZRoutedRpc.instance || world != ZNet.instance.GetWorldUID()) { registered = ZRoutedRpc.instance; world = ZNet.instance.GetWorldUID(); SelectedIds.Clear(); ServerSelectedIds.Clear(); EquippedStates.Clear(); Records.Clear(); HeldIds.Clear(); DecodedItems.Clear(); selectedItem = null; synchronizedId = (synchronizedEquipped = (synchronizedHeld = "")); awaitingSync = false; syncTransaction = ""; ServerStates.Clear(); ClientStates.Clear(); Online.Clear(); Dead.Clear(); Committing.Clear(); RecordOwners.Clear(); pending = null; localId = 0L; registered.Register<ZPackage>("branchofyore.odinsbelt.request", (Action<long, ZPackage>)ReceiveRequest); registered.Register<ZPackage>("branchofyore.odinsbelt.reply", (Action<long, ZPackage>)ReceiveReply); registered.Register<ZPackage>("branchofyore.odinsbelt.snapshot", (Action<long, ZPackage>)ReceiveSnapshot); Keyring.Discover(); } if (ZNet.instance.IsServer()) { ObservePlayers(); } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || localPlayer.GetPlayerID() == 0L) { return; } if (localId != localPlayer.GetPlayerID()) { localId = localPlayer.GetPlayerID(); pending = null; Persistence.RestoreClient(localPlayer); if (localPlayer.m_customData.TryGetValue("branchofyore.odinsbelt.pending", out var value)) { try { pending = Pending.Decode(value); } catch (Exception ex) { Plugin.Instance.Warn("Cannot restore pending belt transfer: " + ex.Message); } } if (pending != null && pending.BeltId == "") { ItemData val = CurrentItem(localPlayer); if (val != null) { pending.BeltId = Identity(val); } } nextSync = 0f; } Pending? obj = pending; if (obj != null && obj.Acknowledged) { CompletePending(localPlayer); } if (!Busy && For(localPlayer)?.Get(0) != null) { Request(2); } if (!Busy || !ClientStates.ContainsKey(localId)) { if (!awaitingSync) { string text = synchronizedId; ItemData val2 = CurrentItem(localPlayer); if (!(text != ((val2 != null) ? Identity(val2) : ""))) { string text2 = synchronizedEquipped; ItemData val3 = EquippedItem(localPlayer); if (!(text2 != ((val3 != null) ? Identity(val3) : "")) && !(synchronizedHeld != Owned(localPlayer)) && SelectedIds.TryGetValue(localId, out string value2) && !(value2 != synchronizedId) && ClientStates.ContainsKey(localId)) { goto IL_0373; } } } if (Time.unscaledTime >= nextSync) { nextSync = Time.unscaledTime + 2f; SendSync(localPlayer); } } goto IL_0373; IL_0373: if (pending != null && !pending.Acknowledged && ClientStates.ContainsKey(localId) && Time.unscaledTime >= nextRetry) { nextRetry = Time.unscaledTime + 2f; Send(pending); } } public static bool PrepareTransfer(ItemData item) { if (BeltInventory.Prefab(item) != "OdinsBelt") { return true; } if (pending != null && Identity(item) == pending.BeltId) { LastMessage = "Wait for the item transfer to finish."; return false; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { SavePlayer(localPlayer); } BeltUI.Close(); return true; } private static void SavePlayer(Player p) { if (pending != null) { p.m_customData["branchofyore.odinsbelt.pending"] = pending.Encode(); } else { p.m_customData.Remove("branchofyore.odinsbelt.pending"); } if (ClientStates.TryGetValue(p.GetPlayerID(), out BeltInventory value) && SelectedIds.TryGetValue(p.GetPlayerID(), out string beltId)) { string value2; ItemData val = ((IEnumerable<ItemData>)((Humanoid)p).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => i.m_customData.TryGetValue("branchofyore.odinsbelt.belt-id", out value2) && value2 == beltId)); if (val != null) { val.m_customData["branchofyore.odinsbelt.contents"] = value.Encode(); } } Persistence.SaveClient(p); } private static void SendSync(Player p) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) string value3; ItemData val = ((pending != null && !pending.Acknowledged) ? ((IEnumerable<ItemData>)((Humanoid)p).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => i.m_customData.TryGetValue("branchofyore.odinsbelt.belt-id", out value3) && value3 == pending.BeltId)) : null) ?? CurrentItem(p); string text = ((val != null) ? Identity(val) : ""); if (!awaitingSync || synchronizedId != text) { syncTransaction = Guid.NewGuid().ToString("N"); } awaitingSync = true; ZPackage val2 = new ZPackage(); val2.Write(0); val2.Write(((Character)p).GetZDOID()); val2.Write(syncTransaction); val2.Write(0L); val2.Write(0); ItemData val3 = val; string text2 = ((val3 != null) ? Identity(val3) : ""); if (val3 != null && !val3.m_customData.ContainsKey("branchofyore.odinsbelt.contents") && !p.m_customData.ContainsKey("branchofyore.odinsbelt.state.migrated") && p.m_customData.TryGetValue("branchofyore.odinsbelt.state", out var value)) { val3.m_customData["branchofyore.odinsbelt.contents"] = value; p.m_customData["branchofyore.odinsbelt.state.migrated"] = text2; } val2.Write((val3 != null && val3.m_customData.TryGetValue("branchofyore.odinsbelt.contents", out var value2)) ? value2 : ""); WriteIdentity(val2, p, text2); synchronizedHeld = Owned(p); synchronizedId = text2; ItemData val4 = EquippedItem(p); synchronizedEquipped = ((val4 != null) ? Identity(val4) : ""); registered.InvokeRoutedRPC(ServerId, "branchofyore.odinsbelt.request", new object[1] { val2 }); } public static bool Store(ItemData item, int slot) { Player localPlayer = Player.m_localPlayer; BeltInventory beltInventory = (Object.op_Implicit((Object)(object)localPlayer) ? Selected(localPlayer) : null); if (!Object.op_Implicit((Object)(object)localPlayer) || registered == null || slot <= 0 || slot >= 21 || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || beltInventory == null || !Ready || pending != null || !((Humanoid)localPlayer).GetInventory().ContainsItem(item) || CurrentItem(localPlayer) == null || !SelectedIds.TryGetValue(localPlayer.GetPlayerID(), out string value) || value != Identity(CurrentItem(localPlayer)) || beltInventory.Get(slot) != null || !Plugin.ItemEnabled(item)) { return false; } ItemData val = item.Clone(); val.m_stack = 1; if (!BeltInventory.ValidSlot(slot, val)) { return false; } ((Humanoid)localPlayer).RemoveEquipAction(item); ((Humanoid)localPlayer).UnequipItem(item, false); string payload = BeltInventory.PackItem(val); if (!((Humanoid)localPlayer).GetInventory().RemoveItem(item, 1)) { return false; } if (Request(1, slot, payload)) { return true; } ((Humanoid)localPlayer).GetInventory().AddItem(val); return false; } public static bool Request(int action, int slot = 0, string payload = "") { Player localPlayer = Player.m_localPlayer; BeltInventory beltInventory = (Object.op_Implicit((Object)(object)localPlayer) ? Selected(localPlayer) : null); if (!Object.op_Implicit((Object)(object)localPlayer) || registered == null || beltInventory == null || !Ready || pending != null || ((Character)localPlayer).IsDead() || CurrentItem(localPlayer) == null || !SelectedIds.TryGetValue(localPlayer.GetPlayerID(), out string value) || value != Identity(CurrentItem(localPlayer))) { return false; } if (action == 2 && (beltInventory.Get(slot) == null || !((Humanoid)localPlayer).GetInventory().CanAddItem(beltInventory.Get(slot), -1))) { return false; } pending = new Pending { Action = action, Slot = slot, Payload = payload, Revision = beltInventory.Revision, BeltId = Identity(CurrentItem(localPlayer)), Transaction = Guid.NewGuid().ToString("N") }; LastMessage = ""; SavePlayer(localPlayer); nextRetry = Time.unscaledTime + 2f; Send(pending); return true; } private static void Send(Pending request) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && registered != null) { ZPackage val = new ZPackage(); val.Write(request.Action); val.Write(((Character)localPlayer).GetZDOID()); val.Write(request.Transaction); val.Write(request.Revision); val.Write(request.Slot); val.Write(request.Payload); WriteIdentity(val, localPlayer, request.BeltId); registered.InvokeRoutedRPC(ServerId, "branchofyore.odinsbelt.request", new object[1] { val }); } } private static void WriteIdentity(ZPackage pkg, Player p, string id) { pkg.Write(id); pkg.Write(Owned(p)); ItemData val = EquippedItem(p); pkg.Write((val != null) ? Identity(val) : ""); pkg.Write((val != null && val.m_customData.TryGetValue("branchofyore.odinsbelt.contents", out var value)) ? value : ""); } private static string RecordPath(long id) { return BeltPath(ServerSelectedIds[id]); } private static string BeltPath(string id) { return Path.Combine(Paths.ConfigPath, "OdinsBelt", world.ToString(), "items", id + ".belt"); } private static BeltInventory Canonical(string id, string imported) { if (Records.TryGetValue(id, out BeltInventory value)) { return value; } string path = BeltPath(id); value = (File.Exists(path) ? BeltInventory.Decode(File.ReadAllText(path)) : BeltInventory.Decode(imported)); Records[id] = value; return value; } private static string Account(long sender) { if (sender == ServerId) { return "local"; } string hostName = ZNet.instance.GetPeer(sender).m_rpc.GetSocket().GetHostName(); using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(hostName))).Replace("-", ""); } private static void Persist(long id, BeltInventory state) { Persistence.Write(RecordPath(id), Encoding.UTF8.GetBytes(state.Encode())); } private static BeltInventory Load(long id, string imported) { BeltInventory beltInventory = Canonical(ServerSelectedIds[id], imported); ServerStates[id] = beltInventory; return beltInventory; } private static bool Authorized(long sender, ZDOID pid, out ZDO player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) player = ZDOMan.instance.GetZDO(pid); if (player == null || player.GetOwner() != sender || player.GetLong(ZDOVars.s_playerID, 0L) == 0L) { return false; } if (sender == ServerId) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return ((Character)Player.m_localPlayer).GetZDOID() == pid; } return false; } ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null || !peer.IsReady()) { return false; } GameObject prefab = ZNetScene.instance.GetPrefab(player.GetPrefab()); if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)prefab.GetComponent<Player>())) { return false; } if (peer.m_characterID == pid || peer.m_characterID == ZDOID.None) { return true; } ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO != null) { return zDO.GetBool(ZDOVars.s_dead, false); } return true; } private static void ReceiveRequest(long sender, ZPackage pkg) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0391: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { return; } try { if (pkg.GetArray().Length > 300000) { return; } int num = pkg.ReadInt(); ZDOID val = pkg.ReadZDOID(); string tx = pkg.ReadString(); long num2 = pkg.ReadLong(); int num3 = pkg.ReadInt(); string text = pkg.ReadString(); string beltId = pkg.ReadString(); string text2 = pkg.ReadString(); string equippedId = pkg.ReadString(); string imported = pkg.ReadString(); if (((beltId == "") ? ((byte)num != 0) : (!Guid.TryParseExact(beltId, "N", out var result))) || (equippedId != "" && !Guid.TryParseExact(equippedId, "N", out result)) || !Authorized(sender, val, out ZDO player)) { return; } long id = player.GetLong(ZDOVars.s_playerID, 0L); if (Online.TryGetValue(id, out (long, ZDOID, Vector3) value) && value.Item1 != sender) { return; } HashSet<string> hashSet = new HashSet<string>(text2.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)); if (hashSet.Count > 300 || (beltId != "" && !hashSet.Contains(beltId)) || (equippedId != "" && !hashSet.Contains(equippedId)) || hashSet.Any((string key) => !Guid.TryParseExact(key, "N", out var _)) || HeldIds.Any<KeyValuePair<long, HashSet<string>>>((KeyValuePair<long, HashSet<string>> pair) => pair.Key != id && Online.ContainsKey(pair.Key) && pair.Value.Contains(beltId))) { return; } HeldIds[id] = hashSet; string text3 = Account(sender); if (RecordOwners.TryGetValue(id, out string value2) && value2 != text3) { ServerStates.Remove(id); } RecordOwners[id] = text3; if (Committing.Contains(id)) { return; } ServerSelectedIds[id] = beltId; BeltInventory state = ((beltId != "") ? Load(id, (num == 0) ? text : "") : new BeltInventory()); ServerStates[id] = state; state.NativeEquipped = NativeEquipped(player) && equippedId == beltId; BeltInventory beltInventory = ((equippedId != "" && NativeEquipped(player)) ? BeltInventory.Decode(Canonical(equippedId, imported).Encode()) : new BeltInventory()); beltInventory.NativeEquipped = equippedId != "" && NativeEquipped(player); EquippedStates[id] = beltInventory; Online[id] = (sender, val, player.GetPosition()); if (num == 0) { long[] array = Online.Keys.ToArray(); foreach (long num5 in array) { if (ServerStates.TryGetValue(num5, out BeltInventory value3)) { Snapshot(sender, num5, value3); } } Snapshot(0L, id, state); Reply(sender, id, tx, accepted: true, state, "", ""); return; } if (tx.Length != 32 || !Guid.TryParseExact(tx, "N", out result) || Committing.Contains(id)) { return; } if (state.LastTransaction == tx) { Reply(sender, id, tx, accepted: true, state, state.LastReceipt, ""); return; } if (player.GetBool(ZDOVars.s_dead, false) || num2 != state.Revision || num3 < 0 || num3 >= 43) { Reply(sender, id, tx, accepted: false, state, "", "Belt changed. Please try again."); return; } BeltInventory next = BeltInventory.Decode(state.Encode()); string receipt = ""; bool flag = false; if (num == 1 && num3 > 0 && num3 < 21 && text.Length <= 65536) { ItemData item = BeltInventory.UnpackItem(text); flag = Plugin.ItemEnabled(item) && next.Put(num3, item); } else { if (num == 2 || num == 4) { ItemData val2 = next.Get(num3); if (val2 != null && (num == 2 || num3 >= 11)) { if (num == 2) { receipt = BeltInventory.PackItem(val2); } next.Inventory.RemoveItem(val2); flag = true; goto IL_07b4; } } if (num == 3) { int num6 = next.FindUtility("Lantern"); if (num6 != 0 && Plugin.LanternEnabled.Value) { next.ActiveSlots ^= 1 << num6; flag = true; goto IL_07b4; } } if (num == 6 && num3 >= 1 && num3 <= 10) { ItemData val3 = next.Get(num3); if (val3 != null && Plugin.ItemEnabled(val3)) { next.ActiveSlots ^= 1 << num3; flag = true; goto IL_07b4; } } if (num == 7 && int.TryParse(text, out var result2) && result2 > 0 && result2 < 21 && num3 > 0 && num3 < 21) { ItemData val4 = next.Get(num3); ItemData val5 = next.Get(result2); if (val4 != null && BeltInventory.ValidSlot(result2, val4) && (val5 == null || BeltInventory.ValidSlot(num3, val5))) { bool flag2 = next.IsActive(num3); bool flag3 = next.IsActive(result2); next.Inventory.RemoveItem(val4); if (val5 != null) { next.Inventory.RemoveItem(val5); } next.Put(result2, val4); if (val5 != null) { next.Put(num3, val5); } if (num3 < 11 && result2 < 11) { next.ActiveSlots &= ~((1 << num3) | (1 << result2)); if (flag2) { next.ActiveSlots |= 1 << result2; } if (flag3) { next.ActiveSlots |= 1 << num3; } } flag = true; } } } goto IL_07b4; IL_07b4: if (!flag) { Reply(sender, id, tx, accepted: false, state, "", "That item cannot go in this slot."); return; } next.PromoteSavedKeys(); next.LanternOn = next.FindUtility("Lantern", activeOnly: true) != 0; next.Revision++; next.LastTransaction = tx; next.LastReceipt = receipt; ServerStates[id] = next; Records[beltId] = next; Committing.Add(id); Persistence.Write(RecordPath(id), Encoding.UTF8.GetBytes(next.Encode()), delegate { Committing.Remove(id); if (equippedId == beltId && NativeEquipped(player)) { BeltInventory beltInventory2 = BeltInventory.Decode(next.Encode()); beltInventory2.NativeEquipped = true; EquippedStates[id] = beltInventory2; } Snapshot(0L, id, next); Reply(sender, id, tx, accepted: true, next, receipt, ""); }, delegate { ServerStates[id] = state; Records[beltId] = state; Committing.Remove(id); Reply(sender, id, tx, accepted: false, state, "", "Could not save belt. Please try again."); }); } catch (Exception ex) { Plugin.Instance.Warn("Belt request rejected: " + ex.Message); } } private static void Snapshot(long peer, long id, BeltInventory state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(id); val.Write(state.Encode()); val.Write(ServerSelectedIds[id]); val.Write(EquippedStates.TryGetValue(id, out BeltInventory value) ? value.Encode() : ""); registered.InvokeRoutedRPC(peer, "branchofyore.odinsbelt.snapshot", new object[1] { val }); } private static void Reply(long peer, long id, string transaction, bool accepted, BeltInventory state, string receipt, string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(id); val.Write(transaction); val.Write(accepted); val.Write(state.Encode()); val.Write(receipt); val.Write(message); val.Write(ServerSelectedIds[id]); registered.InvokeRoutedRPC(peer, "branchofyore.odinsbelt.reply", new object[1] { val }); } private static void ReceiveSnapshot(long sender, ZPackage pkg) { if (sender != ServerId || pkg.GetArray().Length > 300000) { return; } try { long num = pkg.ReadLong(); BeltInventory beltInventory = BeltInventory.Decode(pkg.ReadString()); string text = pkg.ReadString(); BeltInventory value = BeltInventory.Decode(pkg.ReadString()); EquippedStates[num] = value; if (!SelectedIds.TryGetValue(num, out string value2) || value2 != text || !ClientStates.TryGetValue(num, out BeltInventory value3) || beltInventory.Revision >= value3.Revision) { SelectedIds[num] = text; ClientStates[num] = beltInventory; Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && localPlayer.GetPlayerID() == num) { SavePlayer(localPlayer); } } } catch (Exception ex) { Plugin.Instance.Warn("Invalid belt snapshot: " + ex.Message); } } private static void ReceiveReply(long sender, ZPackage pkg) { if (sender != ServerId || pkg.GetArray().Length > 400000) { return; } try { long num = pkg.ReadLong(); string text = pkg.ReadString(); bool flag = pkg.ReadBool(); BeltInventory beltInventory = BeltInventory.Decode(pkg.ReadString()); string text2 = pkg.ReadString(); LastMessage = pkg.ReadString(); string text3 = pkg.ReadString(); Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || num != localPlayer.GetPlayerID()) { return; } if (text == syncTransaction) { if (!flag) { awaitingSync = true; BeltUI.Refresh(); return; } awaitingSync = false; } if (!SelectedIds.TryGetValue(num, out string value) || value != text3 || !ClientStates.TryGetValue(num, out BeltInventory value2) || beltInventory.Revision >= value2.Revision) { SelectedIds[num] = text3; ClientStates[num] = beltInventory; } if (pending != null && pending.Transaction == text) { pending.Acknowledged = true; pending.Receipt = (flag ? text2 : ((pending.Action == 1) ? pending.Payload : "")); SavePlayer(localPlayer); CompletePending(localPlayer); } else { SavePlayer(localPlayer); } BeltUI.Refresh(); } catch (Exception ex) { Plugin.Instance.Warn("Cannot apply belt reply: " + ex.Message); } } private static void CompletePending(Player p) { if (pending == null || !pending.Acknowledged) { return; } ItemData delivered = null; if (!string.IsNullOrEmpty(pending.Receipt)) { ItemData val = BeltInventory.UnpackItem(pending.Receipt); if (!((Humanoid)p).GetInventory().CanAddItem(val, -1) || !((Humanoid)p).GetInventory().AddItem(val)) { LastMessage = "Make room in your inventory to receive the item."; return; } delivered = val; } try { BeltDragAndDrop.TransferFinished(pending.Action, pending.Slot, delivered); } catch (Exception ex) { Plugin.Instance.Warn("Could not place the received item in the selected slot: " + ex.Message); } pending = null; SavePlayer(p); BeltUI.Refresh(); } private static void ObservePlayers() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) KeyValuePair<long, (long, ZDOID, Vector3)>[] array = Online.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<long, (long, ZDOID, Vector3)> keyValuePair = array[i]; ZDO zDO = ZDOMan.instance.GetZDO(keyValuePair.Value.Item2); bool num; if (keyValuePair.Value.Item1 != ServerId) { num = ZNet.instance.GetPeer(keyValuePair.Value.Item1) != null; } else { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { goto IL_008b; } num = ((Character)Player.m_localPlayer).GetZDOID() == keyValuePair.Value.Item2; } if (num) { if (zDO != null) { BeltInventory state = ServerStates[keyValuePair.Key]; if (!NativeEquipped(zDO) && EquippedStates.TryGetValue(keyValuePair.Key, out BeltInventory value) && value.NativeEquipped) { value.NativeEquipped = false; Snapshot(0L, keyValuePair.Key, state); } Online[keyValuePair.Key] = (keyValuePair.Value.Item1, keyValuePair.Value.Item2, zDO.GetPosition()); if (zDO.GetBool(ZDOVars.s_dead, false)) { Dead.Add(keyValuePair.Key); } else { Dead.Remove(keyValuePair.Key); } } continue; } goto IL_008b; IL_008b: if (!Plugin.KeepOnLogout.Value) { DropContents(keyValuePair.Key, keyValuePair.Value.Item3); } Online.Remove(keyValuePair.Key); HeldIds.Remove(keyValuePair.Key); Dead.Remove(keyValuePair.Key); } } public static bool NativeEquipped(ZDO player) { return player.GetInt(ZDOVars.s_utilityItem, 0) == StringExtensionMethods.GetStableHashCode("OdinsBelt"); } private static void DropContents(long id, Vector3 position) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) if (ServerStates.TryGetValue(id, out BeltInventory value) && value.Inventory.GetAllItems().Count != 0) { ItemData[] array = (from i in value.Inventory.GetAllItems() select i.Clone()).ToArray(); BeltInventory beltInventory = new BeltInventory { Revision = value.Revision + 1, LanternOn = value.LanternOn, LastTransaction = value.LastTransaction, LastReceipt = value.LastReceipt }; Persist(id, beltInventory); Records[ServerSelectedIds[id]] = beltInventory; ServerStates[id] = beltInventory; Snapshot(0L, id, beltInventory); for (int num = 0; num < array.Length; num++) { ItemDrop.DropItem(array[num], 1, position + Vector3.up + new Vector3((float)(num % 3) * 0.15f, 0f, (float)(num / 3) * 0.15f), Quaternion.identity); } } } } public static class BeltUI { [HarmonyPatch(typeof(Humanoid), "UnequipItem")] private static class CloseOnUnequip { private static void Postfix(Humanoid __instance, ItemData item) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && item != null && BeltInventory.Prefab(item) == "OdinsBelt" && !item.m_equipped) { Close(); } } } [HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")] private static class RightClick { private static bool Prefix(InventoryGrid grid, ItemData item) { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || item == null || grid.GetInventory() != ((Humanoid)localPlayer).GetInventory()) { return true; } string text = BeltInventory.Prefab(item); if (text == "OdinsBelt") { return true; } if (!Open) { return true; } if (BeltInventory.IsUtility(item)) { BeltInventory state = BeltNetwork.Selected(localPlayer); if (state != null) { int num = Enumerable.Range(1, 10).FirstOrDefault((int s) => state.Get(s) == null); if (num != 0) { BeltNetwork.Store(item, num); } } return false; } if (Keyring.IsKey(text)) { BeltInventory beltInventory = BeltNetwork.Selected(localPlayer); if (beltInventory != null) { for (int num2 = 11; num2 < 21; num2++) { if (beltInventory.Get(num2) == null) { BeltNetwork.Store(item, num2); break; } } } return false; } return true; } } [HarmonyPatch(typeof(InventoryGui), "Hide")] private static class CloseWithInventory { private static void Postfix() { Close(); } } [HarmonyPatch(typeof(InventoryGui), "Update")] private static class OpenBeforeVanillaUse { private static void Prefix() { if (InventoryGui.IsVisible() && (ZInput.GetButtonDown("Use") || Input.GetKeyDown((KeyCode)101)) && TryOpenHoveredBelt()) { ZInput.ResetButtonStatus("Use"); } } } private static GameObject? panel; private static Text? hint; private static Text? status; private static readonly List<(int slot, Button button, Image icon)> Buttons = new List<(int, Button, Image)>(); private static Text? beltStatus; private static readonly Dictionary<int, Button> Activation = new Dictionary<int, Button>(); private static float nextRefresh; public static bool Open { get { if (Object.op_Implicit((Object)(object)panel)) { return panel.activeSelf; } return false; } } public static void Update() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting()) { Close(); } else if ((!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Console.IsVisible() && (Open || !TextInput.IsVisible())) { if (Input.GetKeyDown((KeyCode)101) && InventoryGui.IsVisible()) { TryOpenHoveredBelt(); } if (Open && Input.GetKeyDown((KeyCode)27)) { Close(); } if (Open && Time.unscaledTime >= nextRefresh) { nextRefresh = Time.unscaledTime + 0.3f; Refresh(); } } } public static void Show(ItemData? item = null) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront) || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || (item != null && !BeltNetwork.Select(item))) { return; } if (!Object.op_Implicit((Object)(object)panel)) { Build(); } panel.SetActive(true); BeltNetwork.SynchronizeSelected(); PositionWindow(); if (Object.op_Implicit((Object)(object)InventoryGui.instance)) { InventoryGui instance = InventoryGui.instance; if (!((Animator)AccessTools.Field(typeof(InventoryGui), "m_animator").GetValue(instance)).GetBool("visible")) { instance.Show((Container)null, 0); } } Refresh(); } public static void Close() { BeltDragAndDrop.Cancel(); if (Object.op_Implicit((Object)(object)panel)) { panel.SetActive(false); } } public static void Clear() { Close(); if (Object.op_Implicit((Object)(object)panel)) { Object.Destroy((Object)(object)panel); } panel = null; Buttons.Clear(); Activation.Clear(); } private static Text Text(string value, float x, float y, float width, float height, int size = 18) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) Text component = GUIManager.Instance.CreateText(value, panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(x, y), GUIManager.Instance.AveriaSerifBold, size, new Color(1f, 0.84f, 0.51f), true, Color.black, width, height, false).GetComponent<Text>(); component.alignment = (TextAnchor)4; ((Graphic)component).raycastTarget = false; return component; } private static Button Button(string label, float x, float y, float width, float height, Action click) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown Button component = GUIManager.Instance.CreateButton(label, panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(x, y), width, height).GetComponent<Button>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { click(); }); return component; } private static void Build() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) Buttons.Clear(); panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(260f, -15f), 420f, 520f, false); ((Object)panel).name = "UtilityBeltWindow"; Text("ODIN’S BELT", 0f, 210f, 340f, 32f, 24); Button("×", 180f, 210f, 28f, 28f, Close); beltStatus = Text("", 0f, 185f, 360f, 18f, 14); Text val = Text("UTILITY", 0f, 166f, 360f, 18f); Activation.Clear(); for (int i = 1; i <= 10; i++) { int slot = i; float x = ((i - 1) % 5 - 2) * 74; float num = 105 - (i - 1) / 5 * 87; Activation[slot] = Button("ON", x, num + 41f, 62f, 18f, delegate { BeltNetwork.Request(6, slot); }); Slot(slot, x, num, 64f); } Text val2 = Text("KEYRING", 0f, -30f, 360f, 22f); for (int num2 = 0; num2 < 10; num2++) { Slot(11 + num2, (num2 % 5 - 2) * 74, -80 - num2 / 5 * 70, 64f); } hint = Text("Drag items in or out. Hover an item for details.", 0f, -207f, 370f, 48f, 13); hint.horizontalOverflow = (HorizontalWrapMode)0; hint.verticalOverflow = (VerticalWrapMode)0; status = Text("", 0f, -237f, 370f, 18f, 12); ((Component)val).transform.SetAsLastSibling(); ((Component)val2).transform.SetAsLastSibling(); panel.SetActive(false); } private static void Slot(int slot, float x, float y, float width) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(InventoryGui.instance.m_playerGrid.m_elementPrefab, panel.transform, false); ((Object)val).name = "BeltCell" + slot; RectTransform component = val.GetComponent<RectTransform>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component.anchorMax = val2; component.anchorMin = val2; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(x, y); component.sizeDelta = new Vector2(width, width); InventoryElement component2 = val.GetComponent<InventoryElement>(); component2.Initialize((slot - 1) % 5, (slot - 1) / 5); Button button = component2.m_button; ((UnityEventBase)button.onClick).RemoveAllListeners(); ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { ClickSlot(slot); }); Image icon = component2.m_icon; icon.sprite = null; ((Behaviour)icon).enabled = false; ((Graphic)icon).raycastTarget = false; TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true); for (int num = 0; num < componentsInChildren.Length; num++) { componentsInChildren[num].text = ""; } Image[] array = (Image[])(object)new Image[5] { component2.m_equiped, component2.m_queued, component2.m_noteleport, component2.m_food, component2.m_dropFocus }; foreach (Image val3 in array) { if (Object.op_Implicit((Object)(object)val3)) { ((Component)val3).gameObject.SetActive(false); } } if (Object.op_Implicit((Object)(object)component2.m_selected)) { component2.m_selected.SetActive(false); } if (Object.op_Implicit((Object)(object)component2.m_durability)) { ((Component)component2.m_durability).gameObject.SetActive(false); } if (Object.op_Implicit((Object)(object)component2.m_tooltip)) { ((Behaviour)component2.m_tooltip).enabled = false; } UIDragHandler componentInChildren = val.GetComponentInChildren<UIDragHandler>(); ((Component)componentInChildren).gameObject.AddComponent<BeltSlotHover>().Slot = slot; componentInChildren.m_onBeginDrag = (Action<UIDragHandler>)Delegate.Combine(componentInChildren.m_onBeginDrag, (Action<UIDragHandler>)delegate { BeginSlotDrag(slot); }); componentInChildren.m_onReleasedOn = (Action<UIDragHandler>)Delegate.Combine(componentInChildren.m_onReleasedOn, (Action<UIDragHandler>)delegate { DropOnSlot(slot); }); Buttons.Add((slot, button, icon)); } private static int Actual(int slot) { return slot; } public static void Refresh() { //IL_00cb: 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_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)panel) || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } PositionWindow(); BeltInventory beltInventory = BeltNetwork.Selected(Player.m_localPlayer); if (Object.op_Implicit((Object)(object)beltStatus)) { beltStatus.text = ((beltInventory != null && beltInventory.Equipped) ? "Equipped" : "Right-click the belt in inventory to equip it."); } foreach (var button in Buttons) { ItemData val = beltInventory?.Get(Actual(button.slot)); button.icon.sprite = ((val != null) ? val.GetIcon() : null); ((Behaviour)button.icon).enabled = val != null; ((Graphic)button.icon).color = ((BeltDragAndDrop.Holding && BeltDragAndDrop.Origin == Actual(button.slot)) ? Color.gray : Color.white); ((Selectable)button.button).interactable = beltInventory != null && BeltNetwork.Ready && !BeltNetwork.Busy; } foreach (KeyValuePair<int, Button> item in Activation) { ItemData val2 = beltInventory?.Get(item.Key); bool flag = val2 != null && Plugin.ItemEnabled(val2); ((Component)item.Value).gameObject.SetActive(val2 != null); ((Component)item.Value).GetComponentInChildren<Text>().text = ((flag && beltInventory.IsActive(item.Key)) ? "ON" : "OFF"); ((Graphic)((Component)item.Value).GetComponentInChildren<Text>()).color = (((beltInventory?.IsActive(item.Key) ?? false) && flag) ? new Color(1f, 0.82f, 0.32f) : new Color(0.65f, 0.65f, 0.65f)); ((Selectable)item.Value).interactable = flag && beltInventory != null && beltInventory.Get(item.Key) != null && BeltNetwork.Ready && !BeltNetwork.Busy; } if (Object.op_Implicit((Object)(object)status)) { status.text = ((beltInventory == null || !BeltNetwork.Ready) ? "Synchronizing belt with server..." : ((beltInventory.OverflowCount > 0) ? (beltInventory.OverflowCount + " saved keys waiting for an empty key slot") : BeltNetwork.LastMessage)); } } private static void PositionWindow() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)panel)) { return; } Transform parent = panel.transform.parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val != null) { Rect rect = val.rect; if (!(((Rect)(ref rect)).width <= 0f) && !(((Rect)(ref rect)).height <= 0f)) { float num = Mathf.Min(new float[3] { 1f, (((Rect)(ref rect)).width - 24f) / 420f, (((Rect)(ref rect)).height - 24f) / 520f }); num = Mathf.Max(0.4f, num); panel.transform.localScale = Vector3.one * num; float num2 = Mathf.Max(0f, (((Rect)(ref rect)).width - 420f * num) / 2f - 12f); float num3 = Mathf.Max(0f, (((Rect)(ref rect)).height - 520f * num) / 2f - 12f); panel.GetComponent<RectTransform>().anchoredPosition = new Vector2(Mathf.Clamp(260f, 0f - num2, num2), Mathf.Clamp(-15f, 0f - num3, num3)); } } } public static void Hover(int slot) { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)hint)) { slot = Actual(slot); ItemData val = BeltNetwork.Selected(localPlayer)?.Get(slot); string text = ((slot >= 11) ? "Keys work automatically while equipped." : "Drag items here. Use ON/OFF to activate."); hint.text = ((val != null) ? (Localization.instance.Localize(val.m_shared.m_name) + " — ") : "Empty slot — ") + text; } } private static void ClickSlot(int displaySlot) { ClickActualSlot(Actual(displaySlot)); } public static void BeginSlotDrag(int displaySlot) { BeltDragAndDrop.Begin(Actual(displaySlot)); } public static void EndSlotDrag(PointerEventData pointer) { BeltDragAndDrop.End(pointer); } public static void DropOnSlot(int displaySlot) { if (BeltDragAndDrop.Holding) { if (BeltDragAndDrop.Origin == Actual(displaySlot)) { BeltDragAndDrop.Cancel(); return; } BeltNetwork.Request(7, BeltDragAndDrop.Origin, Actual(displaySlot).ToString()); BeltDragAndDrop.Cancel(); } else { InventoryGui instance = InventoryGui.instance; if (Object.op_Implicit((Object)(object)instance) && AccessTools.Field(typeof(InventoryGui), "m_dragItem").GetValue(instance) != null) { ClickSlot(displaySlot); } } } private static void ClickActualSlot(int slot) { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } BeltInventory beltInventory = BeltNetwork.Selected(localPlayer); if (beltInventory == null) { return; } if (BeltDragAndDrop.Holding) { DropOnSlot(slot); return; } InventoryGui instance = InventoryGui.instance; ItemData val = (ItemData)(Object.op_Implicit((Object)(object)instance) ? /*isinst with value type is only supported in some contexts*/: null); if (val != null) { if (!((Humanoid)localPlayer).GetInventory().ContainsItem(val)) { BeltNetwork.LastMessage = "Move the item into your own inventory first."; } else if (BeltNetwork.Store(val, slot)) { AccessTools.Method(typeof(InventoryGui), "SetupDragItem", (Type[])null, (Type[])null)?.Invoke(instance, new object[3] { null, null, 1 }); } else { BeltNetwork.LastMessage = "That item cannot go in this slot."; } } else if (beltInventory.Get(slot) != null) { BeltDragAndDrop.Begin(slot); } } private static void AddKey() { Player localPlayer = Player.m_localPlayer; BeltInventory state = (Object.op_Implicit((Object)(object)localPlayer) ? BeltNetwork.Selected(localPlayer) : null); if (state != null) { int num = Enumerable.Range(11, 10).FirstOrDefault((int s) => state.Get(s) == null); if (num >= 11) { ClickActualSlot(num); } else { BeltNetwork.LastMessage = "The keyring is full."; } } } public static bool TryOpenHoveredBelt() { //IL_0115: 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) Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)instance) || !InventoryGui.IsVisible()) { return false; } if ((Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Console.IsVisible() || (!Open && TextInput.IsVisible())) { return false; } GameObject val = (Object.op_Implicit((Object)(object)EventSystem.current) ? EventSystem.current.currentSelectedGameObject : null); if (Object.op_Implicit((Object)(object)val)) { InputField component = val.GetComponent<InputField>(); if (component == null || !component.isFocused) { TMP_InputField component2 = val.GetComponent<TMP_InputField>(); if (component2 == null || !component2.isFocused) { goto IL_00a0; } } return false; } goto IL_00a0; IL_00a0: foreach (InventoryGrid item in ((IEnumerable<InventoryGrid>)(object)new InventoryGrid[1] { instance.m_playerGrid }).Concat(((Component)instance).GetComponentsInChildren<InventoryGrid>(true)).Distinct()) { Inventory inventory = item.GetInventory(); if (inventory == null) { continue; } object? obj = AccessTools.Method(typeof(InventoryGrid), "GetHoveredElement", (Type[])null, (Type[])null).Invoke(item, null); InventoryElement val2 = (InventoryElement)((obj is InventoryElement) ? obj : null); if (Object.op_Implicit((Object)(object)val2)) { ItemData itemAt = inventory.GetItemAt(val2.Position.x, val2.Position.y); if (itemAt != null && !(BeltInventory.Prefab(itemAt) != "OdinsBelt") && ((Humanoid)localPlayer).GetInventory().ContainsItem(itemAt)) { Show(itemAt); return true; } } } return false; } } public sealed class BeltSlotHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IEndDragHandler { public int Slot; public void OnPointerEnter(PointerEventData eventData) { BeltUI.Hover(Slot); } public void OnEndDrag(PointerEventData eventData) { BeltUI.EndSlotDrag(eventData); } } internal static class Equipment { private sealed class QuestState { internal SharedData Shared; in