Decompiled source of StackStorageAuthority v0.2.0

plugins/StackStorageAuthority/StackStorageAuthority.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using SSSGame;
using SandSailorStudio.Inventory;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : System.Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : System.Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StackStorageAuthority
{
	[BepInPlugin("michal.ASKA.StackStorageAuthority", "StackStorageAuthority", "0.2.0")]
	public sealed class Plugin : BasePlugin
	{
		internal const string PluginGuid = "michal.ASKA.StackStorageAuthority";

		internal const string PluginName = "StackStorageAuthority";

		internal const string PluginVersion = "0.2.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<int> SmallMultiplier;

		internal static ConfigEntry<int> MediumMultiplier;

		internal static ConfigEntry<int> LargeMultiplier;

		internal static ConfigEntry<int> CartMultiplier;

		internal static ConfigEntry<int> SledMultiplier;

		public override void Load()
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BasePlugin)this).Log;
			SmallMultiplier = ((BasePlugin)this).Config.Bind<int>("General", "Small Items", 3, "Multiplier for small-item building storage.");
			MediumMultiplier = ((BasePlugin)this).Config.Bind<int>("General", "Medium Items", 10, "Multiplier for medium-item building storage.");
			LargeMultiplier = ((BasePlugin)this).Config.Bind<int>("General", "Large Items", 5, "Multiplier for large-item building storage.");
			CartMultiplier = ((BasePlugin)this).Config.Bind<int>("Vehicles", "Cart Multiplier", 5, "Cart stack multiplier; use identical settings on both peers.");
			SledMultiplier = ((BasePlugin)this).Config.Bind<int>("Vehicles", "Sled Multiplier", 3, "Sled stack multiplier; use identical settings on both peers.");
			new Harmony("michal.ASKA.StackStorageAuthority").PatchAll();
			Log.LogInfo((object)"Loaded. Disable ExpandedBuildingStorage and ExpandedCartStorage. Buildings, carts and sleds enabled; multiplayer validation required.");
		}
	}
	internal static class StorageRules
	{
		private static readonly string[] Small = new string[26]
		{
			"Storage_Seeds", "Storage_FoodFarm", "Storage_Wood_Fibers", "Fishing_Baits", "Storage_FoodAll", "Storage_AllNonFood", "Storage_WorkshopSmallItems", "Storage_Vegetables", "Storage_Fruits", "Storage_GathererMaterials",
			"Storage_Leather_Scraps", "Storage_Food_RawRedMeat_Bone", "Storage_WarehouseResin", "Storage_StoneAndMetal_Small", "Storage_Food_WarehouseCheese", "Storage_CoalMakerPile_Output", "Storage_Food_Cooked", "Storage_WarehouseCrawlerResources", "Storage_WarehouseDye", "Storage_WarehouseSmallCraftingMaterials",
			"Storage_WarehouseFoodSilo", "Storage_Wood_FibersResinConeReedsSeeds", "Storage_WorkshopSmallItems_L1", "Storage_WorkshopLinenThread", "Storage_Crawler_Resources", "Storage_StoneAndMetalAndBlood_Small"
		};

		private static readonly string[] Medium = new string[17]
		{
			"Storage_Wood_Bark", "Storage_Wood_Sticks", "Storage_Wood_Firewood", "Storage_Wood_Thatch", "Storage_Wood_LongSticks", "Fishing_WoodRodFishes", "Storage_FurnitureFireWood", "Storage_Horns", "Storage_Leather_HidePelt_T2", "Storage_Food_SmolkrPenHorns",
			"Storage_Arrows", "Storage_ClothingMaterials", "Storage_WorkshopMediumItems_L1", "Storage_Leather_HidePelt_T1", "Storage_Leather_CuredHidePeltT1", "Storage_Leather_CuredHidePeltT2", "Storage_WorkshopLinen"
		};

		private static readonly string[] Large = new string[10] { "Storage_Food_DeerLeg", "Storage_Stone_Raw", "Storage_Carpenter_LargeOutput", "Storage_Carpenter_LongOutput", "Storage_ExplodingSack", "Storage_Wood_Timber", "Storage_Wood_LongSticks", "Storage_Wood_LongSticksL0", "Storage_Wood_HardWoodLog", "Storage_Wood_HardWoodLongSticks" };

		private static readonly string[] SingleSmall = new string[4] { "Storage_WarehouseJotunBlood", "Warehouse_Storage_OreBloom", "Storage_Carpenter_SmallOutput", "Storage_Bloomery_Ore_L1" };

		internal static int StackSizeFor(ItemContainer container, int original)
		{
			if (container == null || (Object)(object)container.itemConfig == (Object)null)
			{
				return original;
			}
			string name = ((Object)container.itemConfig).name;
			checked
			{
				if (Matches(SingleSmall, name))
				{
					return original + 10 * Plugin.SmallMultiplier.Value;
				}
				if (Matches(Small, name))
				{
					return original * Plugin.SmallMultiplier.Value;
				}
				if (Matches(Medium, name))
				{
					return original * Plugin.MediumMultiplier.Value;
				}
				if (Matches(Large, name))
				{
					return original * Plugin.LargeMultiplier.Value;
				}
				return original;
			}
		}

		private static bool Matches(string[] names, string value)
		{
			for (int i = 0; i < names.Length; i++)
			{
				if (string.Equals(names[i], value, (StringComparison)4))
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemContainerComponent), "Initialize")]
	internal static class ItemContainerComponentInitializePatch
	{
		private static readonly Hashtable OriginalStackSizes = new Hashtable();

		[HarmonyPostfix]
		private static void Postfix(ItemContainerComponent __instance)
		{
			if ((Object)(object)__instance == (Object)null || __instance.container == null || VehicleRules.Apply(__instance))
			{
				return;
			}
			ItemContainerType containerType = __instance.container.containerType;
			if ((Object)(object)containerType == (Object)null || containerType.storageClasses == null)
			{
				return;
			}
			Il2CppReferenceArray<StorageClassData> storageClasses = containerType.storageClasses;
			for (int i = 0; i < ((Il2CppArrayBase<StorageClassData>)(object)storageClasses).Length; i++)
			{
				StorageClassData val = ((Il2CppArrayBase<StorageClassData>)(object)storageClasses)[i];
				if (val != null)
				{
					System.IntPtr pointer = ((Il2CppObjectBase)val).Pointer;
					object obj = OriginalStackSizes[(object)(nint)pointer];
					int num;
					if (obj == null)
					{
						num = val.stackSize;
						OriginalStackSizes[(object)(nint)pointer] = num;
					}
					else
					{
						num = (int)obj;
					}
					val.stackSize = StorageRules.StackSizeFor(__instance.container, num);
				}
			}
		}
	}
	internal static class VehicleRules
	{
		private static readonly Dictionary<System.IntPtr, ItemContainerType> Copies = new Dictionary<System.IntPtr, ItemContainerType>();

		internal static bool Apply(ItemContainerComponent component)
		{
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			CartStructure componentInParent = ((Component)component).GetComponentInParent<CartStructure>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return false;
			}
			string name = ((Object)((Component)componentInParent).gameObject).name;
			bool flag = name.Contains("Sled");
			if (!flag && !name.Contains("Cart"))
			{
				return true;
			}
			ItemContainer container = component.container;
			if (container == null || (Object)(object)container.containerType == (Object)null)
			{
				return true;
			}
			ItemContainerType containerType = container.containerType;
			if (Copies.ContainsKey(((Il2CppObjectBase)containerType).Pointer))
			{
				return true;
			}
			Il2CppReferenceArray<StorageClassData> storageClasses = containerType.storageClasses;
			if (storageClasses == null)
			{
				return true;
			}
			int num = Math.Max(1, Math.Min(100, flag ? Plugin.SledMultiplier.Value : Plugin.CartMultiplier.Value));
			bool flag2 = ((Object)containerType).name.Contains("MediumItems");
			bool flag3 = ((Object)containerType).name.Contains("SmallItems");
			if (!flag2 && !flag3 && !((Object)containerType).name.Contains("LargeItems"))
			{
				return true;
			}
			ItemContainerType val = Object.Instantiate<ItemContainerType>(containerType);
			Il2CppReferenceArray<StorageClassData> val2 = new Il2CppReferenceArray<StorageClassData>((long)((Il2CppArrayBase<StorageClassData>)(object)storageClasses).Length);
			for (int i = 0; i < ((Il2CppArrayBase<StorageClassData>)(object)storageClasses).Length; i++)
			{
				StorageClassData val3 = ((Il2CppArrayBase<StorageClassData>)(object)storageClasses)[i];
				if (val3 != null)
				{
					long num2 = (long)num * (long)((flag2 || (flag3 && val3.stackSize == 1)) ? 10 : 1);
					StorageClassData val4 = new StorageClassData();
					val4.storageClass = val3.storageClass;
					val4.stackSize = (int)((val3.stackSize <= 0) ? val3.stackSize : Math.Min(2147483647L, val3.stackSize * num2));
					((Il2CppArrayBase<StorageClassData>)(object)val2)[i] = val4;
				}
			}
			val.storageClasses = val2;
			container.containerType = val;
			Copies.Add(((Il2CppObjectBase)val).Pointer, val);
			Plugin.Log.LogInfo((object)string.Concat(new string[6]
			{
				"Vehicle limits applied: ",
				name,
				", ",
				((Object)containerType).name,
				", multiplier ",
				num.ToString()
			}));
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemContainerComponent), "Initialize")]
	internal static class VehicleInitializePatch
	{
		[HarmonyPrefix]
		private static void Prefix(ItemContainerComponent __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				VehicleRules.Apply(__instance);
			}
		}
	}
}