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 DropCrate v1.0.0
DropCrate.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Splatform; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DropCrate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+62397caa6e8b1cd12b5aec72e5ca03a7ae90940f")] [assembly: AssemblyProduct("DropCrate")] [assembly: AssemblyTitle("DropCrate")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DropCrate { public static class DropCrateConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> ScanIntervalSeconds; public static ConfigEntry<float> ScanRadius; public static ConfigEntry<int> ClusterItemThreshold; public static ConfigEntry<float> ClusterRadius; public static ConfigEntry<float> PlayerDropGracePeriodSeconds; public static ConfigEntry<bool> RespectWards; public static ConfigEntry<int> CrateWidth; public static ConfigEntry<int> CrateHeight; public static ConfigEntry<bool> SweepIntoExistingCrates; public static ConfigEntry<bool> AutoDestroyWhenEmpty; public static ConfigEntry<bool> EnableBeaconLight; public static ConfigEntry<float> CrateScale; public static ConfigEntry<bool> ShowMapPin; public static ConfigEntry<bool> ShowItemCountInPin; public static ConfigEntry<bool> PlaySoundOnSweep; public static ConfigEntry<bool> PlayVfxOnSweep; public static void Init(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown Enabled = config.Bind<bool>("1 - General", "Enabled", true, "Enable or disable DropCrate ground item consolidation to prevent FPS lag."); ScanIntervalSeconds = config.Bind<float>("1 - General", "ScanIntervalSeconds", 3f, new ConfigDescription("How frequently (in seconds) the area around the player is scanned for ground items.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); ScanRadius = config.Bind<float>("1 - General", "ScanRadius", 50f, new ConfigDescription("Maximum distance (in meters) around the local player to look for loose items.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 120f), Array.Empty<object>())); ClusterItemThreshold = config.Bind<int>("1 - General", "ClusterItemThreshold", 10, new ConfigDescription("Minimum number of loose items in a cluster required to condense them into a temporary Drop Crate.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 100), Array.Empty<object>())); ClusterRadius = config.Bind<float>("1 - General", "ClusterRadius", 10f, new ConfigDescription("Maximum distance (in meters) between items to be grouped into the same cluster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 30f), Array.Empty<object>())); PlayerDropGracePeriodSeconds = config.Bind<float>("1 - General", "PlayerDropGracePeriodSeconds", 6f, new ConfigDescription("Grace period (in seconds) for items manually dropped by players before they can be swept. Prevents accidental scooping during player trades.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); RespectWards = config.Bind<bool>("1 - General", "RespectWards", false, "If true, items inside active ward protection fields will NOT be swept into crates."); CrateWidth = config.Bind<int>("2 - Crate Settings", "CrateWidth", 8, new ConfigDescription("Container inventory width (columns).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 10), Array.Empty<object>())); CrateHeight = config.Bind<int>("2 - Crate Settings", "CrateHeight", 6, new ConfigDescription("Container inventory height (rows). Default 6 (8x6 = 48 slots).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 10), Array.Empty<object>())); SweepIntoExistingCrates = config.Bind<bool>("2 - Crate Settings", "SweepIntoExistingCrates", true, "If new loose items drop near an existing un-filled Drop Crate, automatically pull them into it."); AutoDestroyWhenEmpty = config.Bind<bool>("2 - Crate Settings", "AutoDestroyWhenEmpty", true, "Automatically destroy the crate and remove its map pin once completely emptied."); EnableBeaconLight = config.Bind<bool>("2 - Crate Settings", "EnableBeaconLight", true, "Add a warm glowing beacon point-light to the crate so it stands out in grass and darkness."); CrateScale = config.Bind<float>("2 - Crate Settings", "CrateScale", 1f, new ConfigDescription("Visual scale factor for the recovery crate model.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), Array.Empty<object>())); ShowMapPin = config.Bind<bool>("3 - Map Pin", "ShowMapPin", true, "Show a map and mini-map pin for every active Drop Crate."); ShowItemCountInPin = config.Bind<bool>("3 - Map Pin", "ShowItemCountInPin", true, "Show item count in the map pin hover text (e.g. 'Drop Crate (24 items)')."); PlaySoundOnSweep = config.Bind<bool>("4 - Sound & VFX", "PlaySoundOnSweep", true, "Play a chest / salvage sound when loose items are swept into a crate."); PlayVfxOnSweep = config.Bind<bool>("4 - Sound & VFX", "PlayVfxOnSweep", true, "Spawn a subtle poof / particle effect at the crate when items are swept."); } } public class DropCrateController : MonoBehaviour { public static readonly List<DropCrateController> s_activeCrates = new List<DropCrateController>(); private static readonly FieldRef<Inventory, int> s_invWidth = AccessTools.FieldRefAccess<Inventory, int>("m_width"); private static readonly FieldRef<Inventory, int> s_invHeight = AccessTools.FieldRefAccess<Inventory, int>("m_height"); private Container m_container; private ZNetView m_nview; private PinData m_pin; private float m_lastPinUpdate; private bool m_emptied; private bool m_hasHadItems; public Container Container => m_container; public ZNetView NetView => m_nview; public static void PresizeContainer(Container c) { if (!((Object)(object)c == (Object)null)) { c.m_name = "Drop Crate"; c.m_width = DropCrateConfig.CrateWidth.Value; c.m_height = DropCrateConfig.CrateHeight.Value; c.m_checkGuardStone = false; c.m_autoDestroyEmpty = false; Inventory inventory = c.GetInventory(); if (inventory != null) { s_invWidth.Invoke(inventory) = c.m_width; s_invHeight.Invoke(inventory) = c.m_height; } } } private void Awake() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) m_nview = ((Component)this).GetComponent<ZNetView>(); m_container = ((Component)this).GetComponent<Container>(); if ((Object)(object)m_container != (Object)null) { PresizeContainer(m_container); } WearNTear component = ((Component)this).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null) { component.m_noSupportWear = false; component.m_noRoofWear = false; component.m_burnable = false; component.m_ashDamageImmune = true; component.m_health = 100000f; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } GameObject val = DropCrateGlb.LoadGlb("recovery_crate.glb"); if ((Object)(object)val != (Object)null) { ((Object)val).name = "DropCrate_Visual"; val.transform.SetParent(((Component)this).transform, false); float num = Mathf.Max(0.5f, DropCrateConfig.CrateScale.Value); val.transform.localScale = Vector3.one * num; val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; BoxCollider obj = ((Component)this).GetComponent<BoxCollider>() ?? ((Component)this).gameObject.AddComponent<BoxCollider>(); ((Collider)obj).enabled = true; obj.center = new Vector3(0f, 0.4f * num, 0f); obj.size = new Vector3(1f * num, 0.8f * num, 0.8f * num); } if (DropCrateConfig.EnableBeaconLight.Value) { GameObject val2 = new GameObject("CrateBeaconLight"); val2.transform.SetParent(((Component)this).transform, false); val2.transform.localPosition = new Vector3(0f, 1.25f, 0f); Light obj2 = val2.AddComponent<Light>(); obj2.type = (LightType)2; obj2.color = new Color(1f, 0.78f, 0.25f); obj2.range = 8f; obj2.intensity = 1.6f; } s_activeCrates.Add(this); } private void Start() { UpdatePinAndName(); } private void Update() { if (!m_emptied) { if (GetTotalItemCount() > 0) { m_hasHadItems = true; } else if (m_hasHadItems && DropCrateConfig.AutoDestroyWhenEmpty.Value && (Object)(object)m_container != (Object)null) { m_emptied = true; DestroyCrate(); return; } if (Time.time - m_lastPinUpdate > 2f) { m_lastPinUpdate = Time.time; UpdatePinAndName(); } } } public int GetTotalItemCount() { if ((Object)(object)m_container == (Object)null) { return 0; } Inventory inventory = m_container.GetInventory(); if (inventory == null) { return 0; } int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem != null && allItem.m_stack > 0) { num += allItem.m_stack; } } return num; } public void UpdatePinAndName() { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_00c6: 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_00d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_container == (Object)null) { return; } int totalItemCount = GetTotalItemCount(); if (m_container.GetInventory() != null) { m_container.GetInventory().NrOfItems(); } if (totalItemCount > 0) { m_container.m_name = $"Drop Crate ({totalItemCount} items)"; } else { m_container.m_name = "Drop Crate"; } if (!DropCrateConfig.ShowMapPin.Value || (Object)(object)Minimap.instance == (Object)null) { RemovePin(); return; } string text = ((DropCrateConfig.ShowItemCountInPin.Value && totalItemCount > 0) ? $"Drop Crate ({totalItemCount} items)" : "Drop Crate"); if (m_pin == null) { m_pin = Minimap.instance.AddPin(((Component)this).transform.position, DropCratePlugin.DropCratePinType, text, false, false, 0L, default(PlatformUserID)); if (m_pin != null) { m_pin.m_doubleSize = false; } } else { m_pin.m_name = text; m_pin.m_pos = ((Component)this).transform.position; } } private void RemovePin() { if (m_pin != null && (Object)(object)Minimap.instance != (Object)null) { Minimap.instance.RemovePin(m_pin); m_pin = null; } } public void DestroyCrate() { RemovePin(); if ((Object)(object)m_nview != (Object)null && m_nview.IsValid() && (Object)(object)ZNetScene.instance != (Object)null) { if (!m_nview.IsOwner()) { m_nview.ClaimOwnership(); } ZNetScene.instance.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { s_activeCrates.Remove(this); RemovePin(); } } [HarmonyPatch(typeof(Container), "Awake")] internal static class DropCrateContainerAwakePatch { private static void Prefix(Container __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DropCrateController>() != (Object)null) { DropCrateController.PresizeContainer(__instance); } } } [HarmonyPatch(typeof(WearNTear))] internal static class DropCrateWearNTearPatches { [HarmonyPrefix] [HarmonyPatch("UpdateWear")] private static bool PrefixUpdateWear(WearNTear __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DropCrateController>() != (Object)null) { return false; } return true; } [HarmonyPrefix] [HarmonyPatch("HaveSupport")] private static bool PrefixHaveSupport(WearNTear __instance, ref bool __result) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DropCrateController>() != (Object)null) { __result = true; return false; } return true; } [HarmonyPrefix] [HarmonyPatch("GetSupport")] private static bool PrefixGetSupport(WearNTear __instance, ref float __result) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DropCrateController>() != (Object)null) { __result = 1500f; return false; } return true; } [HarmonyPrefix] [HarmonyPatch("Destroy")] private static bool PrefixDestroy(WearNTear __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DropCrateController>() != (Object)null) { return false; } return true; } [HarmonyPrefix] [HarmonyPatch("ApplyDamage")] private static bool PrefixApplyDamage(WearNTear __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DropCrateController>() != (Object)null) { return false; } return true; } } public static class DropCrateGlb { [Serializable] private class GLTFRoot { public GLTFScene[] scenes; public GLTFNode[] nodes; public GLTFMesh[] meshes; public GLTFMaterial[] materials; public GLTFAccessor[] accessors; public GLTFBufferView[] bufferViews; public GLTFTexture[] textures; public GLTFImage[] images; } [Serializable] private class GLTFMesh { public string name; public GLTFPrimitive[] primitives; } [Serializable] private class GLTFPrimitive { public GLTFAttributes attributes; public int indices = -1; public int material = -1; } [Serializable] private class GLTFAttributes { public int POSITION = -1; public int NORMAL = -1; public int TEXCOORD_0 = -1; } [Serializable] private class GLTFNode { public string name; public int mesh = -1; public float[] translation; public float[] rotation; public float[] scale; public int[] children; } [Serializable] private class GLTFMaterial { public string name; public GLTFPBR pbrMetallicRoughness; } [Serializable] private class GLTFPBR { public float[] baseColorFactor; public float? metallicFactor; public float? roughnessFactor; public GLTFTextureInfo baseColorTexture; } [Serializable] private class GLTFTextureInfo { public int index = -1; } [Serializable] private class GLTFImage { public int bufferView = -1; public string name; } [Serializable] private class GLTFTexture { public int source = -1; } [Serializable] private class GLTFAccessor { public int bufferView; public int byteOffset; public int componentType; public int count; public string type; } [Serializable] private class GLTFBufferView { public int byteOffset; public int byteLength; public int byteStride; } [Serializable] private class GLTFScene { public int[] nodes; } private static readonly Dictionary<string, GameObject> s_cachedPrefabs = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); public static GameObject LoadGlb(string fileNameOrPath, Material sourceMaterialTemplate = null) { string text = (File.Exists(fileNameOrPath) ? fileNameOrPath : DropCratePlugin.PluginFile(fileNameOrPath)); if (string.IsNullOrEmpty(text) || !File.Exists(text)) { DropCratePlugin.Log.LogError((object)("DropCrateGlb: Model file not found: " + fileNameOrPath)); return null; } if (s_cachedPrefabs.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { GameObject obj = Object.Instantiate<GameObject>(value); obj.SetActive(true); return obj; } try { byte[] array = File.ReadAllBytes(text); if (array.Length < 20 || BitConverter.ToUInt32(array, 0) != 1179937895) { DropCratePlugin.Log.LogError((object)("DropCrateGlb: File is not a valid GLB: " + text)); return null; } int num = 12; string text2 = null; byte[] array2 = null; while (num < array.Length && num + 8 <= array.Length) { uint num2 = BitConverter.ToUInt32(array, num); uint num3 = BitConverter.ToUInt32(array, num + 4); num += 8; switch (num3) { case 1313821514u: text2 = Encoding.UTF8.GetString(array, num, (int)num2); break; case 5130562u: array2 = new byte[num2]; Buffer.BlockCopy(array, num, array2, 0, (int)num2); break; } num += (int)num2; num = (num + 3) & -4; } if (string.IsNullOrEmpty(text2) || array2 == null) { return null; } Shader shader = (((Object)(object)sourceMaterialTemplate != (Object)null) ? sourceMaterialTemplate.shader : FindValidShader()); GameObject val = ParseGLTF(text2, array2, shader, Path.GetFileNameWithoutExtension(text)); if ((Object)(object)val != (Object)null) { val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); s_cachedPrefabs[text] = val; GameObject obj2 = Object.Instantiate<GameObject>(val); obj2.SetActive(true); return obj2; } } catch (Exception ex) { DropCratePlugin.Log.LogError((object)("DropCrateGlb: Exception loading GLB " + text + ": " + ex)); } return null; } public static Shader FindValidShader() { Shader val = Shader.Find("Custom/Piece") ?? Shader.Find("Custom/StaticObject") ?? Shader.Find("Custom/Creature") ?? Shader.Find("Standard"); if ((Object)(object)val != (Object)null) { return val; } try { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); foreach (Shader val2 in array) { if (((Object)val2).name == "Custom/Piece" || ((Object)val2).name == "Custom/StaticObject" || ((Object)val2).name == "Standard") { return val2; } } } catch { } return Shader.Find("Diffuse") ?? Shader.Find("Unlit/Texture"); } private static GameObject ParseGLTF(string json, byte[] binData, Shader shader, string rootName) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //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_0117: Expected O, but got Unknown //IL_059f: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Expected O, but got Unknown //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_075b: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(rootName); GLTFRoot gLTFRoot = JsonConvert.DeserializeObject<GLTFRoot>(json); if (gLTFRoot == null) { return null; } GLTFBufferView[] bufferViews = gLTFRoot.bufferViews ?? new GLTFBufferView[0]; GLTFAccessor[] array = gLTFRoot.accessors ?? new GLTFAccessor[0]; GLTFMesh[] array2 = gLTFRoot.meshes ?? new GLTFMesh[0]; GLTFMaterial[] array3 = gLTFRoot.materials ?? new GLTFMaterial[0]; GLTFNode[] array4 = gLTFRoot.nodes ?? new GLTFNode[0]; GLTFTexture[] array5 = gLTFRoot.textures ?? new GLTFTexture[0]; GLTFImage[] images = gLTFRoot.images ?? new GLTFImage[0]; Dictionary<int, Texture2D> texCache = new Dictionary<int, Texture2D>(); Func<int, Texture2D> func = delegate(int imageIndex) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown if (imageIndex < 0 || imageIndex >= images.Length) { return (Texture2D)null; } if (texCache.TryGetValue(imageIndex, out var value)) { return value; } GLTFImage gLTFImage = images[imageIndex]; if (gLTFImage.bufferView < 0 || gLTFImage.bufferView >= bufferViews.Length) { return (Texture2D)null; } GLTFBufferView gLTFBufferView = bufferViews[gLTFImage.bufferView]; if (gLTFBufferView.byteOffset + gLTFBufferView.byteLength > binData.Length) { return (Texture2D)null; } byte[] array16 = new byte[gLTFBufferView.byteLength]; Buffer.BlockCopy(binData, gLTFBufferView.byteOffset, array16, 0, gLTFBufferView.byteLength); Texture2D val7 = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val7, array16)) { Object.Destroy((Object)(object)val7); return (Texture2D)null; } ((Object)val7).name = gLTFImage.name ?? $"img_{imageIndex}"; ((Texture)val7).wrapMode = (TextureWrapMode)0; ((Texture)val7).filterMode = (FilterMode)1; texCache[imageIndex] = val7; return val7; }; Mesh[] array6 = (Mesh[])(object)new Mesh[array2.Length]; Material[][] array7 = new Material[array2.Length][]; Vector3[] array8 = (Vector3[])(object)new Vector3[array2.Length]; for (int num = 0; num < array2.Length; num++) { GLTFMesh gLTFMesh = array2[num]; Mesh val2 = new Mesh { name = (gLTFMesh.name ?? $"Mesh_{num}") }; if (gLTFMesh.primitives != null && gLTFMesh.primitives.Length != 0) { List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<Vector2> list3 = new List<Vector2>(); List<int[]> list4 = new List<int[]>(); List<Material> list5 = new List<Material>(); for (int num2 = 0; num2 < gLTFMesh.primitives.Length; num2++) { GLTFPrimitive gLTFPrimitive = gLTFMesh.primitives[num2]; int count = list.Count; GLTFAttributes attributes = gLTFPrimitive.attributes; Vector3[] array9 = ((attributes != null && attributes.POSITION >= 0 && gLTFPrimitive.attributes.POSITION < array.Length) ? ReadVec3Accessor(array[gLTFPrimitive.attributes.POSITION], bufferViews, binData) : null); GLTFAttributes attributes2 = gLTFPrimitive.attributes; Vector3[] array10 = ((attributes2 != null && attributes2.NORMAL >= 0 && gLTFPrimitive.attributes.NORMAL < array.Length) ? ReadVec3Accessor(array[gLTFPrimitive.attributes.NORMAL], bufferViews, binData) : null); GLTFAttributes attributes3 = gLTFPrimitive.attributes; Vector2[] array11 = ((attributes3 != null && attributes3.TEXCOORD_0 >= 0 && gLTFPrimitive.attributes.TEXCOORD_0 < array.Length) ? ReadVec2Accessor(array[gLTFPrimitive.attributes.TEXCOORD_0], bufferViews, binData) : null); if (array9 != null) { list.AddRange(array9); if (array10 != null && array10.Length == array9.Length) { list2.AddRange(array10); } else { for (int num3 = 0; num3 < array9.Length; num3++) { list2.Add(Vector3.up); } } if (array11 != null && array11.Length == array9.Length) { list3.AddRange(array11); } else { for (int num4 = 0; num4 < array9.Length; num4++) { list3.Add(Vector2.zero); } } } if (gLTFPrimitive.indices >= 0 && gLTFPrimitive.indices < array.Length) { int[] array12 = ReadIndicesAccessor(array[gLTFPrimitive.indices], bufferViews, binData); if (array12 != null) { int[] array13 = new int[array12.Length]; for (int num5 = 0; num5 < array12.Length; num5++) { array13[num5] = array12[num5] + count; } list4.Add(array13); } } if (gLTFPrimitive.material >= 0 && gLTFPrimitive.material < array3.Length) { GLTFMaterial gLTFMaterial = array3[gLTFPrimitive.material]; Texture2D baseTexture = null; int num6 = gLTFMaterial.pbrMetallicRoughness?.baseColorTexture?.index ?? (-1); if (num6 >= 0 && num6 < array5.Length) { baseTexture = func(array5[num6].source); } list5.Add(CreateMaterial(gLTFMaterial, shader, baseTexture)); } else { list5.Add(new Material(shader) { color = Color.white }); } } if (list.Count > 65535) { val2.indexFormat = (IndexFormat)1; } Vector3 val3 = Vector3.zero; if (list.Count > 0) { Vector3 val4 = list[0]; Vector3 val5 = list[0]; for (int num7 = 1; num7 < list.Count; num7++) { val4 = Vector3.Min(val4, list[num7]); val5 = Vector3.Max(val5, list[num7]); } val3 = (val4 + val5) * 0.5f; for (int num8 = 0; num8 < list.Count; num8++) { List<Vector3> list6 = list; int index = num8; list6[index] -= val3; } } array8[num] = val3; val2.SetVertices(list); val2.SetNormals(list2); val2.SetUVs(0, list3); val2.subMeshCount = list4.Count; for (int num9 = 0; num9 < list4.Count; num9++) { val2.SetTriangles(list4[num9], num9); } array7[num] = list5.ToArray(); } val2.RecalculateNormals(); val2.RecalculateBounds(); array6[num] = val2; } GameObject[] array14 = (GameObject[])(object)new GameObject[array4.Length]; for (int num10 = 0; num10 < array4.Length; num10++) { array14[num10] = new GameObject(array4[num10].name ?? $"Node_{num10}"); GLTFNode gLTFNode = array4[num10]; if (gLTFNode.translation != null && gLTFNode.translation.Length == 3) { array14[num10].transform.localPosition = new Vector3(gLTFNode.translation[0], gLTFNode.translation[1], gLTFNode.translation[2]); } if (gLTFNode.rotation != null && gLTFNode.rotation.Length == 4) { array14[num10].transform.localRotation = new Quaternion(gLTFNode.rotation[0], gLTFNode.rotation[1], gLTFNode.rotation[2], gLTFNode.rotation[3]); } if (gLTFNode.scale != null && gLTFNode.scale.Length == 3) { array14[num10].transform.localScale = new Vector3(gLTFNode.scale[0], gLTFNode.scale[1], gLTFNode.scale[2]); } } for (int num11 = 0; num11 < array4.Length; num11++) { if (array4[num11].children == null) { continue; } int[] children = array4[num11].children; foreach (int num12 in children) { if (num12 >= 0 && num12 < array14.Length) { array14[num12].transform.SetParent(array14[num11].transform, false); } } } for (int num13 = 0; num13 < array4.Length; num13++) { GLTFNode gLTFNode2 = array4[num13]; GameObject val6 = array14[num13]; if (gLTFNode2.mesh >= 0 && gLTFNode2.mesh < array6.Length) { if (gLTFNode2.translation == null || gLTFNode2.translation.Length < 3) { Transform transform = val6.transform; transform.localPosition += array8[gLTFNode2.mesh]; } val6.AddComponent<MeshFilter>().sharedMesh = array6[gLTFNode2.mesh]; ((Renderer)val6.AddComponent<MeshRenderer>()).sharedMaterials = array7[gLTFNode2.mesh]; } } bool flag = false; GLTFScene[] array15 = gLTFRoot.scenes ?? new GLTFScene[0]; foreach (GLTFScene gLTFScene in array15) { if (gLTFScene.nodes == null) { continue; } int[] children = gLTFScene.nodes; foreach (int num15 in children) { if (num15 >= 0 && num15 < array14.Length) { array14[num15].transform.SetParent(val.transform, false); flag = true; } } } if (!flag) { for (int num16 = 0; num16 < array14.Length; num16++) { if ((Object)(object)array14[num16].transform.parent == (Object)null) { array14[num16].transform.SetParent(val.transform, false); } } } return val; } private static Vector3[] ReadVec3Accessor(GLTFAccessor accessor, GLTFBufferView[] bufferViews, byte[] binData) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (accessor == null || accessor.bufferView < 0 || accessor.bufferView >= bufferViews.Length) { return null; } GLTFBufferView gLTFBufferView = bufferViews[accessor.bufferView]; int num = gLTFBufferView.byteOffset + accessor.byteOffset; int count = accessor.count; int num2 = ((gLTFBufferView.byteStride > 0) ? gLTFBufferView.byteStride : 12); Vector3[] array = (Vector3[])(object)new Vector3[count]; for (int i = 0; i < count; i++) { int num3 = num + i * num2; if (num3 + 12 <= binData.Length) { array[i] = new Vector3(BitConverter.ToSingle(binData, num3), BitConverter.ToSingle(binData, num3 + 4), BitConverter.ToSingle(binData, num3 + 8)); } } return array; } private static Vector2[] ReadVec2Accessor(GLTFAccessor accessor, GLTFBufferView[] bufferViews, byte[] binData) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (accessor == null || accessor.bufferView < 0 || accessor.bufferView >= bufferViews.Length) { return null; } GLTFBufferView gLTFBufferView = bufferViews[accessor.bufferView]; int num = gLTFBufferView.byteOffset + accessor.byteOffset; int count = accessor.count; int num2 = ((gLTFBufferView.byteStride > 0) ? gLTFBufferView.byteStride : 8); Vector2[] array = (Vector2[])(object)new Vector2[count]; for (int i = 0; i < count; i++) { int num3 = num + i * num2; if (num3 + 8 <= binData.Length) { array[i] = new Vector2(BitConverter.ToSingle(binData, num3), 1f - BitConverter.ToSingle(binData, num3 + 4)); } } return array; } private static int[] ReadIndicesAccessor(GLTFAccessor accessor, GLTFBufferView[] bufferViews, byte[] binData) { if (accessor == null || accessor.bufferView < 0 || accessor.bufferView >= bufferViews.Length) { return null; } GLTFBufferView gLTFBufferView = bufferViews[accessor.bufferView]; int num = gLTFBufferView.byteOffset + accessor.byteOffset; int count = accessor.count; int[] array = new int[count]; if (accessor.componentType == 5123) { int num2 = ((gLTFBufferView.byteStride > 0) ? gLTFBufferView.byteStride : 2); for (int i = 0; i < count; i++) { int num3 = num + i * num2; if (num3 + 2 <= binData.Length) { array[i] = BitConverter.ToUInt16(binData, num3); } } } else if (accessor.componentType == 5125) { int num4 = ((gLTFBufferView.byteStride > 0) ? gLTFBufferView.byteStride : 4); for (int j = 0; j < count; j++) { int num5 = num + j * num4; if (num5 + 4 <= binData.Length) { array[j] = BitConverter.ToInt32(binData, num5); } } } else if (accessor.componentType == 5121) { for (int k = 0; k < count; k++) { int num6 = num + k; if (num6 < binData.Length) { array[k] = binData[num6]; } } } return array; } private static Material CreateMaterial(GLTFMaterial mat, Shader shader, Texture2D baseTexture) { //IL_000a: 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_0025: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(shader ?? FindValidShader()) { name = (mat.name ?? "DropCrateMat") }; if ((Object)(object)baseTexture != (Object)null) { val.mainTexture = (Texture)(object)baseTexture; if (val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", (Texture)(object)baseTexture); } if (val.HasProperty("_BaseMap")) { val.SetTexture("_BaseMap", (Texture)(object)baseTexture); } if (val.HasProperty("_Albedo")) { val.SetTexture("_Albedo", (Texture)(object)baseTexture); } } Color val2 = Color.white; if (mat.pbrMetallicRoughness != null) { GLTFPBR pbrMetallicRoughness = mat.pbrMetallicRoughness; if (pbrMetallicRoughness.baseColorFactor != null && pbrMetallicRoughness.baseColorFactor.Length == 4) { Color white = default(Color); ((Color)(ref white))..ctor(pbrMetallicRoughness.baseColorFactor[0], pbrMetallicRoughness.baseColorFactor[1], pbrMetallicRoughness.baseColorFactor[2], pbrMetallicRoughness.baseColorFactor[3]); if (white.a <= 0.01f || ((Object)(object)baseTexture != (Object)null && white.r <= 0.08f && white.g <= 0.08f && white.b <= 0.08f)) { white = Color.white; } val2 = white; } if (pbrMetallicRoughness.metallicFactor.HasValue && val.HasProperty("_Metallic")) { val.SetFloat("_Metallic", Mathf.Clamp01(pbrMetallicRoughness.metallicFactor.Value)); } if (pbrMetallicRoughness.roughnessFactor.HasValue) { float num = Mathf.Clamp01(1f - pbrMetallicRoughness.roughnessFactor.Value); if (val.HasProperty("_Glossiness")) { val.SetFloat("_Glossiness", num); } if (val.HasProperty("_Smoothness")) { val.SetFloat("_Smoothness", num); } } } val.color = val2; if (val.HasProperty("_Color")) { val.SetColor("_Color", val2); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", val2); } if (val.HasProperty("_Cull")) { val.SetInt("_Cull", 0); } val.renderQueue = 2000; return val; } } public class DropCrateManager : MonoBehaviour { private static readonly Dictionary<ItemDrop, float> s_playerDropTimes = new Dictionary<ItemDrop, float>(); private static readonly MethodInfo s_containerSave = typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldRef<List<ItemDrop>> s_instancesRef = AccessTools.StaticFieldRefAccess<List<ItemDrop>>(AccessTools.Field(typeof(ItemDrop), "s_instances")); private float m_lastScanTime; public static void RegisterPlayerDrop(ItemDrop drop) { if ((Object)(object)drop != (Object)null) { s_playerDropTimes[drop] = Time.time; } } public static bool IsUnderGracePeriod(ItemDrop drop) { if ((Object)(object)drop == (Object)null) { return false; } if (s_playerDropTimes.TryGetValue(drop, out var value)) { if (Time.time - value < DropCrateConfig.PlayerDropGracePeriodSeconds.Value) { return true; } s_playerDropTimes.Remove(drop); } return false; } private void Update() { if (DropCrateConfig.Enabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null) && Time.time - m_lastScanTime >= DropCrateConfig.ScanIntervalSeconds.Value) { m_lastScanTime = Time.time; ScanAndConsolidate(); } } public static void ScanAndConsolidate(int? overrideThreshold = null) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } Vector3 position = ((Component)localPlayer).transform.position; float value = DropCrateConfig.ScanRadius.Value; float num = value * value; CleanupStaleDrops(); List<ItemDrop> list = new List<ItemDrop>(); List<ItemDrop> list2 = ((s_instancesRef != null) ? s_instancesRef.Invoke() : null); if (list2 != null) { for (int i = 0; i < list2.Count; i++) { ItemDrop val = list2[i]; if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && (!((Object)(object)((Component)val).transform.parent != (Object)null) || !((Object)(object)((Component)val).GetComponentInParent<Character>() != (Object)null)) && !IsUnderGracePeriod(val)) { Vector3 position2 = ((Component)val).transform.position; Vector3 val2 = position2 - position; if (!(((Vector3)(ref val2)).sqrMagnitude > num) && (!DropCrateConfig.RespectWards.Value || !IsProtectedByActiveWard(position2)) && val.m_itemData != null && val.m_itemData.m_stack > 0) { list.Add(val); } } } } if (list.Count == 0) { return; } if (DropCrateConfig.SweepIntoExistingCrates.Value && DropCrateController.s_activeCrates.Count > 0) { float value2 = DropCrateConfig.ClusterRadius.Value; for (int num2 = DropCrateController.s_activeCrates.Count - 1; num2 >= 0; num2--) { DropCrateController dropCrateController = DropCrateController.s_activeCrates[num2]; if (!((Object)(object)dropCrateController == (Object)null) && !((Object)(object)dropCrateController.Container == (Object)null)) { Inventory inventory = dropCrateController.Container.GetInventory(); if (inventory != null) { Vector3 position3 = ((Component)dropCrateController).transform.position; int num3 = 0; for (int num4 = list.Count - 1; num4 >= 0; num4--) { ItemDrop val3 = list[num4]; if ((Object)(object)val3 == (Object)null) { list.RemoveAt(num4); } else if (Vector3.Distance(((Component)val3).transform.position, position3) <= value2 && TryAddItemToInventory(inventory, val3)) { num3++; list.RemoveAt(num4); } } if (num3 > 0) { SaveContainer(dropCrateController.Container); dropCrateController.UpdatePinAndName(); PlaySweepFeedback(position3); } } } } } int num5 = (overrideThreshold.HasValue ? Mathf.Max(1, overrideThreshold.Value) : DropCrateConfig.ClusterItemThreshold.Value); if (list.Count < num5) { return; } float value3 = DropCrateConfig.ClusterRadius.Value; HashSet<ItemDrop> hashSet = new HashSet<ItemDrop>(list); while (hashSet.Count >= num5) { HashSet<ItemDrop>.Enumerator enumerator = hashSet.GetEnumerator(); if (!enumerator.MoveNext()) { break; } ItemDrop current = enumerator.Current; hashSet.Remove(current); List<ItemDrop> list3 = new List<ItemDrop> { current }; Vector3 position4 = ((Component)current).transform.position; List<ItemDrop> list4 = new List<ItemDrop>(); foreach (ItemDrop item in hashSet) { if ((Object)(object)item != (Object)null && Vector3.Distance(((Component)item).transform.position, position4) <= value3) { list4.Add(item); } } foreach (ItemDrop item2 in list4) { list3.Add(item2); hashSet.Remove(item2); } if (list3.Count >= num5) { ConsolidateClusterIntoNewCrate(list3); } } } private static void ConsolidateClusterIntoNewCrate(List<ItemDrop> cluster) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) if (cluster == null || cluster.Count == 0) { return; } Vector3 val = Vector3.zero; int num = 0; for (int i = 0; i < cluster.Count; i++) { if ((Object)(object)cluster[i] != (Object)null) { val += ((Component)cluster[i]).transform.position; num++; } } if (num == 0) { return; } Vector3 val2 = val / (float)num; float num2 = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val2, ref num2)) { val2.y = Mathf.Max(num2 + 0.15f, val2.y); } GameObject val3 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("DFG_DropCrate") : null); if ((Object)(object)val3 == (Object)null) { DropCratePlugin.Log.LogError((object)"DropCrate: Prefab DFG_DropCrate not found!"); return; } GameObject obj = Object.Instantiate<GameObject>(val3, val2, Quaternion.identity); Container component = obj.GetComponent<Container>(); DropCrateController component2 = obj.GetComponent<DropCrateController>(); if (!((Object)(object)component != (Object)null) || component.GetInventory() == null) { return; } Inventory inventory = component.GetInventory(); int num3 = 0; for (int j = 0; j < cluster.Count; j++) { ItemDrop val4 = cluster[j]; if (!((Object)(object)val4 == (Object)null) && TryAddItemToInventory(inventory, val4)) { num3++; } } SaveContainer(component); if ((Object)(object)component2 != (Object)null) { component2.UpdatePinAndName(); } PlaySweepFeedback(val2); DropCratePlugin.Log.LogInfo((object)$"DropCrate: Swept {num3} items into new Drop Crate at {val2}."); } public static bool TryAddItemToInventory(Inventory inv, ItemDrop drop) { if (inv == null || (Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_stack <= 0) { return false; } ItemData itemData = drop.m_itemData; EnsureDropPrefab(itemData); int stack = itemData.m_stack; if (inv.AddItem(itemData)) { DestroyItemDrop(drop); return true; } if (itemData.m_stack < stack && itemData.m_stack > 0) { drop.m_itemData.m_stack = itemData.m_stack; ZNetView component = ((Component)drop).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.GetZDO().Set(ZDOVars.s_stack, itemData.m_stack, false); } return true; } return false; } private static void DestroyItemDrop(ItemDrop drop) { if ((Object)(object)drop == (Object)null) { return; } ZNetView component = ((Component)drop).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && (Object)(object)ZNetScene.instance != (Object)null) { if (!component.IsOwner()) { component.ClaimOwnership(); } ZNetScene.instance.Destroy(((Component)drop).gameObject); } else { Object.Destroy((Object)(object)((Component)drop).gameObject); } } public static void EnsureDropPrefab(ItemData item) { if (item == null || (Object)(object)item.m_dropPrefab != (Object)null || (Object)(object)ObjectDB.instance == (Object)null || item.m_shared == null) { return; } foreach (GameObject item2 in ObjectDB.instance.m_items) { if (!((Object)(object)item2 == (Object)null)) { ItemDrop component = item2.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData?.m_shared != null && component.m_itemData.m_shared.m_name == item.m_shared.m_name) { item.m_dropPrefab = item2; break; } } } } public static void SaveContainer(Container c) { if ((Object)(object)c == (Object)null) { return; } try { s_containerSave?.Invoke(c, null); } catch { } } public static bool IsProtectedByActiveWard(Vector3 point) { //IL_0000: 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_0062: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(point, 32f); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] == (Object)null) { continue; } PrivateArea componentInParent = ((Component)array[i]).GetComponentInParent<PrivateArea>(); if (!((Object)(object)componentInParent == (Object)null)) { ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool(ZDOVars.s_enabled, false) && Vector3.Distance(point, ((Component)componentInParent).transform.position) <= componentInParent.m_radius) { return true; } } } return false; } private static void CleanupStaleDrops() { if (s_playerDropTimes.Count == 0) { return; } float time = Time.time; List<ItemDrop> list = null; foreach (KeyValuePair<ItemDrop, float> s_playerDropTime in s_playerDropTimes) { if ((Object)(object)s_playerDropTime.Key == (Object)null || time - s_playerDropTime.Value > 60f) { if (list == null) { list = new List<ItemDrop>(); } list.Add(s_playerDropTime.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { s_playerDropTimes.Remove(list[i]); } } } private static void PlaySweepFeedback(Vector3 pos) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_00ad: 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_00bc: 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) try { if (DropCrateConfig.PlayVfxOnSweep.Value && (Object)(object)ZNetScene.instance != (Object)null) { GameObject val = ZNetScene.instance.GetPrefab("vfx_ItemDrop") ?? ZNetScene.instance.GetPrefab("vfx_loot_spawn"); if ((Object)(object)val != (Object)null) { Object.Instantiate<GameObject>(val, pos + Vector3.up * 0.4f, Quaternion.identity); } } if (DropCrateConfig.PlaySoundOnSweep.Value && (Object)(object)ZNetScene.instance != (Object)null) { GameObject val2 = ZNetScene.instance.GetPrefab("sfx_chest_open") ?? ZNetScene.instance.GetPrefab("sfx_build_hammer_wood"); if ((Object)(object)val2 != (Object)null) { Object.Instantiate<GameObject>(val2, pos + Vector3.up * 0.4f, Quaternion.identity); } } } catch { } } } [HarmonyPatch(typeof(ItemDrop), "OnPlayerDrop")] internal static class ItemDropOnPlayerDropPatch { private static void Postfix(ItemDrop __instance) { if ((Object)(object)__instance != (Object)null) { DropCrateManager.RegisterPlayerDrop(__instance); } } } [BepInPlugin("com.dfg.dropcrate", "DropCrate", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class DropCratePlugin : BaseUnityPlugin { public const string PluginGUID = "com.dfg.dropcrate"; public const string PluginName = "DropCrate"; public const string PluginVersion = "1.0.0"; private static bool s_pinRegistered; private Harmony m_harmony; public static DropCratePlugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } public static PinType DropCratePinType { get; set; } = (PinType)3; public static string PluginPath => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); public static string PluginFile(string fileName) { if (string.IsNullOrEmpty(fileName)) { return string.Empty; } return Path.Combine(PluginPath, fileName); } private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; DropCrateConfig.Init(((BaseUnityPlugin)this).Config); DropCratePrefabs.Init(); try { m_harmony = new Harmony("com.dfg.dropcrate"); m_harmony.PatchAll(); } catch (Exception ex) { Log.LogError((object)("DropCrate: failed to apply Harmony patches: " + ex)); } ((Component)this).gameObject.AddComponent<DropCrateManager>(); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new DropCrateSweepCommand()); Log.LogInfo((object)"DropCrate v1.0.0 initialized successfully."); } public static void RegisterCustomPin() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_005e: 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_00d3: 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_00df: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) if (s_pinRegistered || (Object)(object)Minimap.instance == (Object)null) { return; } try { Sprite val = null; string path = PluginFile("icon.png"); if (File.Exists(path)) { byte[] array = File.ReadAllBytes(path); Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, false); if (ImageConversion.LoadImage(val2, array)) { val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); } } if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab("piece_chest_wood"); val = ((prefab == null) ? null : prefab.GetComponent<Piece>()?.m_icon); } if ((Object)(object)val != (Object)null) { PinType val3 = (PinType)Minimap.instance.m_icons.Count; SpriteData item = new SpriteData { m_name = val3, m_icon = val }; Minimap.instance.m_icons.Add(item); DropCratePinType = val3; s_pinRegistered = true; Log.LogInfo((object)"DropCrate: Registered custom Minimap pin sprite."); } } catch (Exception ex) { Log.LogWarning((object)("DropCrate: Failed to register custom pin icon, defaulting to Icon3: " + ex.Message)); DropCratePinType = (PinType)3; } } private void OnDestroy() { Harmony harmony = m_harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Minimap), "Start")] internal static class MinimapStartPatch { private static void Postfix() { DropCratePlugin.RegisterCustomPin(); } } internal sealed class DropCrateSweepCommand : ConsoleCommand { public override string Name => "dropcrate_sweep"; public override string Help => "DropCrate: Manually trigger an immediate scan and consolidation of nearby ground items. Usage: dropcrate_sweep [minThreshold]"; public override void Run(string[] args) { if ((Object)(object)Player.m_localPlayer == (Object)null) { Console.instance.Print("dropcrate_sweep: No local player found."); return; } int num = DropCrateConfig.ClusterItemThreshold.Value; if (args != null && args.Length > 1 && int.TryParse(args[1], out var result)) { num = Mathf.Max(1, result); } DropCrateManager.ScanAndConsolidate(num); Console.instance.Print($"DropCrate: Sweep executed (threshold: {num} items)."); } } public static class DropCratePrefabs { public const string DropCratePrefabName = "DFG_DropCrate"; private static bool s_registered; public static void Init() { PrefabManager.OnVanillaPrefabsAvailable += RegisterPrefabs; LocalizationManager.Instance.AddToken("dfg_dropcrate_name", "Drop Crate", false); LocalizationManager.Instance.AddToken("dfg_dropcrate_desc", "Temporary salvage crate consolidating loose items to reduce world lag.", false); } private static void RegisterPrefabs() { if (s_registered) { return; } s_registered = true; try { GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_wood"); if ((Object)(object)prefab == (Object)null) { DropCratePlugin.Log.LogError((object)"DropCrate: Could not find piece_chest_wood source prefab!"); return; } GameObject val = PrefabManager.Instance.CreateClonedPrefab("DFG_DropCrate", prefab); ((Object)val).name = "DFG_DropCrate"; Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_name = "$dfg_dropcrate_name"; component.m_description = "$dfg_dropcrate_desc"; component.m_canBeRemoved = false; } Container component2 = val.GetComponent<Container>(); if ((Object)(object)component2 != (Object)null) { component2.m_name = "Drop Crate"; component2.m_width = DropCrateConfig.CrateWidth.Value; component2.m_height = DropCrateConfig.CrateHeight.Value; component2.m_checkGuardStone = false; component2.m_autoDestroyEmpty = false; } WearNTear component3 = val.GetComponent<WearNTear>(); if ((Object)(object)component3 != (Object)null) { component3.m_noSupportWear = false; component3.m_noRoofWear = false; component3.m_burnable = false; component3.m_ashDamageImmune = true; component3.m_health = 100000f; } val.AddComponent<DropCrateController>(); PrefabManager.Instance.AddPrefab(val); DropCratePlugin.Log.LogInfo((object)"DropCrate: Successfully registered DFG_DropCrate prefab."); } catch (Exception ex) { DropCratePlugin.Log.LogError((object)("DropCrate: Failed to register DFG_DropCrate prefab: " + ex)); } } } }