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 ChestLootSigns v0.1.0
plugins/ChestLootSigns/ChestLootSigns.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using Blackforge.Hot; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 Blackforge { public static class Chests { private struct Face { public Vector3 center; public Vector3 normal; public float width; public float height; } private class Entry { public Container chest; public Action changed; public Face[] faces; public GameObject sign; public string shown = ""; } private const string Sign = "bf_loot"; private const string Wagon = "bf_wagon"; private const string Measured = "bf_chests_measured"; private static readonly string[] Built = new string[4] { "piece_chest_wood", "piece_chest", "piece_chest_blackmetal", "piece_chest_private" }; private static readonly Face[] WagonFaces = WagonWalls(); private static HotHost host; private static readonly List<Entry> entries = new List<Entry>(); private static readonly Dictionary<string, Face[]> layouts = new Dictionary<string, Face[]>(); private static bool failed; private const float SignHeight = 0.6f; private const float SignMiddle = 0.42f; private const float Fill = 0.9f; private const float Off = 0.01f; public static void Load(HotHost from) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown host = from; host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(Container), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Chests), "Seen", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Seen(array[i]); } } public static void Unload() { foreach (Entry entry in entries) { if ((Object)(object)entry.chest != (Object)null && entry.chest.GetInventory() != null) { Inventory inventory = entry.chest.GetInventory(); inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, entry.changed); } if ((Object)(object)entry.sign != (Object)null) { Object.Destroy((Object)(object)entry.sign); } } entries.Clear(); layouts.Clear(); failed = false; host = null; } private static void Seen(Container __instance) { if (host == null || (Object)(object)__instance == (Object)null || __instance.GetInventory() == null) { return; } string text = ((Object)((Component)__instance).gameObject).name.Split('(')[0].Trim(); if (text != "bf_wagon" && !Built.Contains(text)) { return; } entries.RemoveAll((Entry old) => (Object)(object)old.chest == (Object)null); if (entries.Any((Entry old) => (Object)(object)old.chest == (Object)(object)__instance)) { return; } try { if (!layouts.TryGetValue(text, out var value)) { value = ((text == "bf_wagon") ? WagonFaces : Fit(__instance, text)); layouts[text] = value; } if (value.Length != 0) { Entry entry = new Entry { chest = __instance, faces = value }; entry.changed = delegate { Draw(entry); }; Inventory inventory = __instance.GetInventory(); inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, entry.changed); entries.Add(entry); Draw(entry); } } catch (Exception error) { Warn(error); } } private static void Draw(Entry entry) { //IL_0185: 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_0196: Expected O, but got Unknown //IL_01d0: 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_01de: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) if (host == null || (Object)(object)entry.chest == (Object)null) { return; } try { List<ItemData> list = (from val5 in entry.chest.GetInventory().GetAllItems() where val5.m_shared.m_icons != null && val5.m_shared.m_icons.Length != 0 group val5 by val5.m_shared.m_name into @group orderby @group.Count() descending, @group.Key select @group.First()).ToList(); string text = string.Join("|", list.Select((ItemData val5) => $"{val5.m_shared.m_name}:{val5.m_variant}")); if (text == entry.shown && ((Object)(object)entry.sign != (Object)null || list.Count == 0)) { return; } entry.shown = text; if ((Object)(object)entry.sign != (Object)null) { Object.Destroy((Object)(object)entry.sign); entry.sign = null; } if (list.Count == 0) { return; } int layer = ((Component)entry.chest).gameObject.layer; entry.sign = new GameObject("bf_loot") { layer = layer }; entry.sign.transform.SetParent(((Component)entry.chest).transform, false); Face[] faces = entry.faces; Vector3 val2 = default(Vector3); for (int num = 0; num < faces.Length; num++) { Face face = faces[num]; GameObject val = new GameObject("face") { layer = layer }; val.transform.SetParent(entry.sign.transform, false); val.transform.localPosition = face.center; val.transform.localRotation = Quaternion.LookRotation(-face.normal, Vector3.up); (int columns, int rows, float cell) tuple = Grid(list.Count, face.width, face.height); int item = tuple.columns; int item2 = tuple.rows; float item3 = tuple.cell; for (int num2 = 0; num2 < list.Count; num2++) { Sprite icon = list[num2].GetIcon(); if (!((Object)(object)icon == (Object)null)) { Bounds bounds = icon.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num3 = item3 * 0.92f / Mathf.Max(new float[3] { size.x, size.y, 0.001f }); ((Vector3)(ref val2))..ctor(((float)(num2 % item) - (float)(item - 1) / 2f) * item3, ((float)(item2 - 1) / 2f - (float)(num2 / item)) * item3, 0f); GameObject val3 = new GameObject("icon") { layer = layer }; val3.transform.SetParent(val.transform, false); Transform transform = val3.transform; Vector3 val4 = val2; bounds = icon.bounds; transform.localPosition = val4 - ((Bounds)(ref bounds)).center * num3; val3.transform.localScale = new Vector3(num3, num3, 1f); val3.AddComponent<SpriteRenderer>().sprite = icon; } } } } catch (Exception error) { Warn(error); } } private static (int columns, int rows, float cell) Grid(int count, float width, float height) { (int, int, float) result = (1, count, 0f); for (int i = 1; i <= count; i++) { int num = (count + i - 1) / i; float num2 = Mathf.Min(width / (float)i, height / (float)num); if (num2 > result.Item3) { result = (i, num, num2); } } return result; } private static Face[] Fit(Container chest, string prefab) { //IL_0022: 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_0044: 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_00ad: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) Bounds box; string parts; bool flag = Measure(chest, out box, out parts); Tell($"{prefab} at {((Component)chest).transform.position}, scale {((Component)chest).transform.lossyScale}, box {((Bounds)(ref box)).size}, parts: {parts}"); GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null); Container val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Container>(true) : null); if ((Object)(object)val2 != (Object)null && Measure(val2, out var box2, out var parts2)) { Tell($"{prefab} as the game has it, box {((Bounds)(ref box2)).size}, parts: {parts2}"); box = box2; flag = true; } if (!flag || ((Bounds)(ref box)).size.y < 0.05f) { host.Log.LogWarning((object)("chests: " + prefab + " has no model to measure, it gets no loot sign")); return new Face[0]; } float height = ((Bounds)(ref box)).size.y * 0.6f; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref box)).center.x, ((Bounds)(ref box)).min.y + ((Bounds)(ref box)).size.y * 0.42f, ((Bounds)(ref box)).center.z); host.Log.LogInfo((object)$"chests: the loot sign of {prefab} hangs on a box of {((Bounds)(ref box)).size.x:0.00} by {((Bounds)(ref box)).size.z:0.00} by {((Bounds)(ref box)).size.y:0.00} m"); return new Face[2] { new Face { center = val3 + Vector3.right * (((Bounds)(ref box)).extents.x + 0.01f), normal = Vector3.right, width = ((Bounds)(ref box)).size.z * 0.9f, height = height }, new Face { center = val3 + Vector3.left * (((Bounds)(ref box)).extents.x + 0.01f), normal = Vector3.left, width = ((Bounds)(ref box)).size.z * 0.9f, height = height } }; } private static bool Measure(Container chest, out Bounds box, out string parts) { //IL_0008: 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_00be: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)chest).transform; box = default(Bounds); bool flag = false; List<string> list = new List<string>(); MeshFilter[] componentsInChildren = ((Component)transform).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { string text = (((Object)(object)val.sharedMesh == (Object)null) ? "no mesh" : (((Object)(object)((Component)val).GetComponent<MeshRenderer>() == (Object)null) ? "no renderer" : (((Object)val).name.Contains("snow") ? "snow" : (((Object)(object)chest.m_open != (Object)null && ((Component)val).transform.IsChildOf(chest.m_open.transform)) ? "open lid" : null)))); Bounds val2 = default(Bounds); if ((Object)(object)val.sharedMesh != (Object)null) { Matrix4x4 val3 = transform.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix; Bounds bounds = val.sharedMesh.bounds; for (int j = 0; j < 8; j++) { Vector3 val4 = ((Matrix4x4)(ref val3)).MultiplyPoint3x4(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3(((j & 1) == 0) ? (-1f) : 1f, ((j & 2) == 0) ? (-1f) : 1f, ((j & 4) == 0) ? (-1f) : 1f))); if (j == 0) { ((Bounds)(ref val2))..ctor(val4, Vector3.zero); } ((Bounds)(ref val2)).Encapsulate(val4); if (text == null) { if (!flag) { box = new Bounds(val4, Vector3.zero); flag = true; } ((Bounds)(ref box)).Encapsulate(val4); } } } list.Add(string.Format("{0}/{1} {2} {3}", ((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name : "", ((Object)val).name, ((Bounds)(ref val2)).size, text ?? "counted")); } parts = string.Join("; ", list); return flag; } private static void Tell(string text) { host.Log.LogInfo((object)("chests: measured " + text)); } private static Face[] WagonWalls() { //IL_003a: 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_0046: 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_0052: Unknown result type (might be due to invalid IL or missing references) List<Face> list = new List<Face>(); int[] array = new int[2] { -1, 1 }; foreach (int num in array) { list.Add(new Face { center = new Vector3((float)num * 0.935f, 1.66f, 1.1f), normal = Vector3.right * (float)num, width = 0.62f, height = 0.68f }); } return list.ToArray(); } private static void Warn(Exception error) { if (!failed && host != null) { failed = true; host.Log.LogWarning((object)$"chests: a loot sign failed, said only once: {error}"); } } } [BepInPlugin("vladasz.chestlootsigns", "Chest Loot Signs", "0.1.0")] public class ChestLootSignsPlugin : BaseUnityPlugin { public const string Id = "vladasz.chestlootsigns"; public const string Number = "0.1.0"; private void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown HotHost hotHost = new HotHost(((BaseUnityPlugin)this).Logger, new Harmony("vladasz.chestlootsigns"), "0.1.0"); if (!hotHost.IsDedicatedServer) { Chests.Load(hotHost); } } } } namespace Blackforge.Hot { public sealed class HotHost { public ManualLogSource Log { get; } public Harmony Harmony { get; } public string Version { get; } public bool IsDedicatedServer => (int)SystemInfo.graphicsDeviceType == 4; internal HotHost(ManualLogSource log, Harmony harmony, string version) { Log = log; Harmony = harmony; Version = version; } public byte[] ReadAsset(string relative) { return File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(typeof(HotHost).Assembly.Location), relative)); } public void UnregisterRpc(IEnumerable<string> names) { if (ZRoutedRpc.instance == null) { return; } foreach (string name in names) { ZRoutedRpc.instance.m_functions.Remove(StringExtensionMethods.GetStableHashCode(name)); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }