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 Prime Chest Sizes v1.0.0
BepInEx/plugins/PrimeChestSizes/PrimeChestSizes.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Prime Chest Sizes")] [assembly: AssemblyDescription("Configurable chest capacities for Valheim")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [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 PrimeChestSizes { internal readonly struct GridSize { public readonly int Width; public readonly int Height; public GridSize(int width, int height) { Width = width; Height = height; } } internal static class SizePolicy { public static GridSize Fit(int width, int height, int vanillaWidth, int vanillaHeight, IEnumerable<GridSize> occupied) { int num = Math.Max(vanillaWidth, Math.Max(1, Math.Min(8, width))); int num2 = Math.Max(vanillaHeight, Math.Max(1, Math.Min(20, height))); foreach (GridSize item in occupied) { if (item.Width >= 0) { num = Math.Max(num, item.Width + 1); } if (item.Height >= 0) { num2 = Math.Max(num2, item.Height + 1); } } return new GridSize(num, num2); } public static string PrefabName(string name) { if (!name.EndsWith("(Clone)", StringComparison.Ordinal)) { return name; } return name.Substring(0, name.Length - "(Clone)".Length).TrimEnd(); } } [BepInPlugin("prime.valheim.chestsizes", "Prime Chest Sizes", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { private sealed class ChestOptions { public ConfigEntry<bool> Enabled; public ConfigEntry<int> Columns; public ConfigEntry<int> Rows; } private sealed class OriginalSize { public int Width; public int Height; public ChestOptions Options; } public const string Guid = "prime.valheim.chestsizes"; private static Plugin instance; private Harmony harmony; private bool errorLogged; private readonly Dictionary<string, ChestOptions> options = new Dictionary<string, ChestOptions>(StringComparer.Ordinal); private static readonly ConditionalWeakTable<object, OriginalSize> originals = new ConditionalWeakTable<object, OriginalSize>(); private static Type containerType; private static Type viewType; private static FieldInfo containerWidth; private static FieldInfo containerHeight; private static FieldInfo containerInventory; private static FieldInfo inventoryWidth; private static FieldInfo inventoryHeight; private static FieldInfo gridPosition; private static FieldInfo positionX; private static FieldInfo positionY; private static MethodInfo getItems; private static MethodInfo getZdo; private static MethodInfo isOwner; private static MethodInfo zdoGet; private static MethodInfo zdoSet; private static bool stringKeys; private void Awake() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown instance = this; Add("Wooden Chest", "piece_chest_wood", 8, 4); Add("Personal Chest", "piece_chest_private", 6, 4); Add("Reinforced Chest", "piece_chest", 8, 6); Add("Black Metal Chest", "piece_chest_blackmetal", 8, 8); Add("Barrel", "piece_chest_barrel", 8, 4); Add("Grausten Chest", "piece_chest_grausten", 8, 10); ((BaseUnityPlugin)this).Config.Save(); try { ResolveApi(); harmony = new Harmony("prime.valheim.chestsizes"); Patch("Awake", "BeforeAwake", "AfterLoad"); Patch("Load", "BeforeLoad", "AfterLoad"); Patch("Save", "BeforeSave", null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Prime Chest Sizes 1.0.0 loaded. Edit prime.valheim.chestsizes.cfg with the game closed. Multiplayer: use identical configs on all players and the server."); } catch (Exception ex) { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } ((BaseUnityPlugin)this).Logger.LogError((object)("Prime Chest Sizes could not initialize against this Valheim version; patches were removed. " + ex)); } } private void Add(string section, string prefab, int columns, int rows) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown options.Add(prefab, new ChestOptions { Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>(section, "Enabled", true, "Use custom capacity for " + prefab + ". False requests vanilla size while protecting occupied slots. Restart after editing."), Columns = ((BaseUnityPlugin)this).Config.Bind<int>(section, "Columns", columns, new ConfigDescription("Horizontal slots (1-8). Never reduced below vanilla width or occupied slots. Restart after editing.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())), Rows = ((BaseUnityPlugin)this).Config.Bind<int>(section, "Rows", rows, new ConfigDescription("Vertical slots (1-20). Never reduced below vanilla height or occupied slots. Extra rows use Valheim's container scrolling. Restart after editing.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())) }); } private static Type RequireType(string name) { return AccessTools.TypeByName(name) ?? throw new MissingMemberException(name); } private static FieldInfo Field(Type type, string name) { return AccessTools.Field(type, name) ?? throw new MissingFieldException(type.FullName, name); } private static MethodInfo Method(Type type, string name, params Type[] args) { return AccessTools.Method(type, name, args, (Type[])null) ?? throw new MissingMethodException(type.FullName, name); } private static void ResolveApi() { containerType = RequireType("Container"); viewType = RequireType("ZNetView"); Type type = RequireType("Inventory"); Type type2 = RequireType("ZDO"); Type type3 = RequireType("ItemDrop").GetNestedType("ItemData", BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMemberException("ItemDrop.ItemData"); containerWidth = Field(containerType, "m_width"); containerHeight = Field(containerType, "m_height"); containerInventory = Field(containerType, "m_inventory"); inventoryWidth = Field(type, "m_width"); inventoryHeight = Field(type, "m_height"); getItems = Method(type, "GetAllItems"); gridPosition = Field(type3, "m_gridPos"); positionX = Field(gridPosition.FieldType, "x"); positionY = Field(gridPosition.FieldType, "y"); getZdo = Method(viewType, "GetZDO"); isOwner = Method(viewType, "IsOwner"); zdoGet = AccessTools.Method(type2, "GetInt", new Type[2] { typeof(string), typeof(int) }, (Type[])null); zdoSet = AccessTools.Method(type2, "Set", new Type[2] { typeof(string), typeof(int) }, (Type[])null); stringKeys = zdoGet != null && zdoSet != null; if (!stringKeys) { zdoGet = Method(type2, "GetInt", typeof(int), typeof(int)); zdoSet = Method(type2, "Set", typeof(int), typeof(int)); } Method(containerType, "Awake"); Method(containerType, "Load"); Method(containerType, "Save"); } private void Patch(string original, string prefix, string postfix) { //IL_0025: 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) harmony.Patch((MethodBase)Method(containerType, original), (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool TryOriginal(object container, out OriginalSize original) { if (originals.TryGetValue(container, out original)) { return true; } Component val = (Component)((container is Component) ? container : null); if ((Object)(object)val == (Object)null || !instance.options.TryGetValue(SizePolicy.PrefabName(((Object)val.gameObject).name), out var value)) { return false; } original = new OriginalSize { Width = (int)containerWidth.GetValue(container), Height = (int)containerHeight.GetValue(container), Options = value }; originals.Add(container, original); return true; } private static GridSize Requested(OriginalSize original) { return SizePolicy.Fit(original.Options.Enabled.Value ? original.Options.Columns.Value : original.Width, original.Options.Enabled.Value ? original.Options.Rows.Value : original.Height, original.Width, original.Height, Array.Empty<GridSize>()); } private static object View(object container) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return ((Component)container).GetComponent(viewType); } private static object Zdo(object container) { object obj = View(container); if (obj != null) { return getZdo.Invoke(obj, null); } return null; } private static object Key(string key) { if (!stringKeys) { return StableHash(key); } return key; } private static int StableHash(string text) { int num = 5381; int num2 = num; for (int i = 0; i < text.Length; i += 2) { num = ((num << 5) + num) ^ text[i]; if (i == text.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ text[i + 1]; } return num + num2 * 1566083941; } private static void Prepare(object container) { if (TryOriginal(container, out var original)) { GridSize gridSize = Requested(original); int num = gridSize.Width; int num2 = gridSize.Height; object obj = Zdo(container); if (obj != null) { num = Math.Max(num, (int)zdoGet.Invoke(obj, new object[2] { Key("prime.valheim.chestsizes.width"), num })); num2 = Math.Max(num2, (int)zdoGet.Invoke(obj, new object[2] { Key("prime.valheim.chestsizes.height"), num2 })); } object value = containerInventory.GetValue(container); if (value != null) { num = Math.Max(num, (int)inventoryWidth.GetValue(value)); num2 = Math.Max(num2, (int)inventoryHeight.GetValue(value)); inventoryWidth.SetValue(value, num); inventoryHeight.SetValue(value, num2); } containerWidth.SetValue(container, num); containerHeight.SetValue(container, num2); } } private static IEnumerable<GridSize> Positions(object inventory) { foreach (object item in (IEnumerable)getItems.Invoke(inventory, null)) { object value = gridPosition.GetValue(item); yield return new GridSize((int)positionX.GetValue(value), (int)positionY.GetValue(value)); } } private static void Resize(object container) { if (TryOriginal(container, out var original)) { object value = containerInventory.GetValue(container); if (value != null) { GridSize gridSize = Requested(original); GridSize gridSize2 = SizePolicy.Fit(gridSize.Width, gridSize.Height, original.Width, original.Height, Positions(value)); containerWidth.SetValue(container, gridSize2.Width); containerHeight.SetValue(container, gridSize2.Height); inventoryWidth.SetValue(value, gridSize2.Width); inventoryHeight.SetValue(value, gridSize2.Height); } } } private static void Remember(object container) { if (!TryOriginal(container, out var _)) { return; } object value = containerInventory.GetValue(container); object obj = View(container); if (value != null && obj != null && (bool)isOwner.Invoke(obj, null)) { object obj2 = getZdo.Invoke(obj, null); if (obj2 != null) { zdoSet.Invoke(obj2, new object[2] { Key("prime.valheim.chestsizes.width"), inventoryWidth.GetValue(value) }); zdoSet.Invoke(obj2, new object[2] { Key("prime.valheim.chestsizes.height"), inventoryHeight.GetValue(value) }); } } } private static void Guard(Action action) { try { action(); } catch (Exception ex) { if (!instance.errorLogged) { instance.errorLogged = true; ((BaseUnityPlugin)instance).Logger.LogError((object)("Chest resize failed. Exit without further chest changes and check compatibility. " + ex)); } } } private static void BeforeAwake(object __instance) { Guard(delegate { Prepare(__instance); }); } private static void BeforeLoad(object __instance) { Guard(delegate { Prepare(__instance); }); } private static void AfterLoad(object __instance) { Guard(delegate { Resize(__instance); }); } private static void BeforeSave(object __instance) { Guard(delegate { Remember(__instance); }); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } }