Decompiled source of NoItemSpawnLimit v1.0.4

NoItemSpawnLimit.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NoItemSpawnLimit.Patches;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("HeroHanex")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4+ae064179cfbe351311265fb28ee0df0d7820ef1a")]
[assembly: AssemblyProduct("NoItemSpawnLimit")]
[assembly: AssemblyTitle("NoItemSpawnLimit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 NoItemSpawnLimit
{
	[BepInPlugin("HeroHanex.NoItemSpawnLimit", "NoItemSpawnLimit", "1.0.4")]
	public class NoItemSpawnLimit : BaseUnityPlugin
	{
		internal static NoItemSpawnLimit Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			ConfigManager.Init(((BaseUnityPlugin)this).Config);
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
			Harmony.PatchAll(typeof(LevelGeneratorPatch));
			Harmony.PatchAll(typeof(PunManagerPatch));
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
}
namespace NoItemSpawnLimit.Patches
{
	public class ConfigManager
	{
		private static readonly ManualLogSource Logger = Logger.CreateLogSource("NoItemSpawnLimit");

		private static ConfigFile? _config;

		private static ConfigEntry<bool>? RemoveSpawnLimit;

		private static readonly Dictionary<string, ConfigEntry<int>> itemMaxAmountConfigs = new Dictionary<string, ConfigEntry<int>>();

		private const int defaultMaxAmount = 10000;

		private static readonly char[] invalidChars = new char[7] { '=', '\n', '\t', '"', '\'', '[', ']' };

		public static void Init(ConfigFile config)
		{
			_config = config;
			RemoveSpawnLimit = config.Bind<bool>("General", "RemoveSpawnLimit", true, "Remove item spawn limit");
			Logger.LogInfo((object)"ConfigManager initialized.");
			config.Save();
		}

		public static void LoadMaxItemConfig()
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			if (_config == null)
			{
				Logger.LogError((object)"ConfigManager: _config is null. Init() wasn't called.");
				return;
			}
			if ((Object)(object)StatsManager.instance == (Object)null || StatsManager.instance.itemDictionary.Count == 0)
			{
				Logger.LogWarning((object)"StatsManager or itemDictionary is not ready. It should be ready once loaded into a level.");
				return;
			}
			foreach (KeyValuePair<string, Item> item in StatsManager.instance.itemDictionary)
			{
				if (!itemMaxAmountConfigs.ContainsKey(item.Key))
				{
					int maxAmount = item.Value.maxAmount;
					string text = SanitizeString(item.Key);
					ConfigEntry<int> value = _config.Bind<int>("ItemLimits", text, maxAmount, new ConfigDescription("Max amount for item '" + item.Key + "'", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>()));
					itemMaxAmountConfigs[item.Key] = value;
				}
			}
			if (RemoveSpawnLimit == null)
			{
				RemoveSpawnLimit = _config.Bind<bool>("General", "RemoveSpawnLimit", true, "Remove item spawn limit");
				Logger.LogInfo((object)"RemoveSpawnLimit config was null. Created RemoveSpawnLimit config.");
			}
			_config.Save();
			if (RemoveSpawnLimit.Value)
			{
				Logger.LogInfo((object)$"RemoveSpawnLimit is enabled. Applying predefined config of {10000} to all items...");
				ApplyPredefinedConfig();
			}
			else
			{
				Logger.LogInfo((object)"RemoveSpawnLimit is disabled. Applying per-item config...");
				ApplyItemConfig();
			}
		}

		private static void ApplyItemConfig()
		{
			foreach (KeyValuePair<string, ConfigEntry<int>> itemMaxAmountConfig in itemMaxAmountConfigs)
			{
				if (!StatsManager.instance.itemDictionary.TryGetValue(itemMaxAmountConfig.Key, out var value))
				{
					Logger.LogWarning((object)("Item '" + itemMaxAmountConfig.Key + "' not found in itemDictionary."));
					break;
				}
				value.maxAmount = itemMaxAmountConfig.Value.Value;
			}
		}

		private static void ApplyPredefinedConfig()
		{
			foreach (KeyValuePair<string, Item> item in StatsManager.instance.itemDictionary)
			{
				item.Value.maxAmount = 10000;
			}
		}

		private static string SanitizeString(string input)
		{
			char[] array = invalidChars;
			foreach (char oldChar in array)
			{
				input = input.Replace(oldChar, '_');
			}
			return input;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator))]
	public class LevelGeneratorPatch
	{
		private static readonly ManualLogSource Logger = Logger.CreateLogSource("NoItemSpawnLimit");

		[HarmonyPostfix]
		[HarmonyPatch("GenerateDone")]
		private static void GenerateDonePatch(LevelGenerator __instance)
		{
			if (StatsManager.instance.itemDictionary != null && StatsManager.instance.itemDictionary.Count != 0)
			{
				Logger.LogInfo((object)"LevelGeneratorPatch: Level generation done. Loading item config...");
				ConfigManager.LoadMaxItemConfig();
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	public class PunManagerPatch
	{
		private static readonly ManualLogSource Logger = Logger.CreateLogSource("NoItemSpawnLimit");

		private const float SpawnOffsetFacing = 7f;

		private const float SpawnOffsetHeight = 2f;

		private static Vector3 SpawnOffset = new Vector3(0f, 2f, 7f);

		private static Vector3 SpawnOffsetLobby = new Vector3(7f, 2f, 0f);

		[HarmonyPrefix]
		[HarmonyPatch("TruckPopulateItemVolumes")]
		private static void TruckPopulateItemVolumesPatch(PunManager __instance)
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Invalid comparison between Unknown and I4
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: 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)
			ItemManager.instance.spawnedItems.Clear();
			if (SemiFunc.IsNotMasterClient())
			{
				return;
			}
			List<ItemVolume> itemVolumes = __instance.itemManager.itemVolumes;
			List<Item> purchasedItems = __instance.itemManager.purchasedItems;
			Logger.LogInfo((object)$"Initial shelfVolumes: {itemVolumes.Count}, purchasedItems: {purchasedItems.Count}");
			while (itemVolumes.Count > 0 && purchasedItems.Count > 0)
			{
				bool flag = false;
				for (int i = 0; i < purchasedItems.Count; i++)
				{
					Item item = purchasedItems[i];
					ItemVolume val = itemVolumes.Find((ItemVolume v) => v.itemVolume == item.itemVolume);
					if ((Object)(object)val != (Object)null)
					{
						__instance.SpawnItem(item, val);
						itemVolumes.Remove(val);
						purchasedItems.RemoveAt(i);
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					break;
				}
			}
			Logger.LogInfo((object)$"After shelf fill: shelfVolumes: {itemVolumes.Count}, purchasedItems: {purchasedItems.Count}");
			if (purchasedItems.Count > 0)
			{
				List<SpawnPoint> list = Object.FindObjectsOfType<SpawnPoint>().ToList();
				ListExtension.Shuffle<SpawnPoint>((IList<SpawnPoint>)list);
				int num = 0;
				foreach (Item item2 in purchasedItems.ToList())
				{
					if ((int)item2.itemType == 5)
					{
						Logger.LogInfo((object)("Ignoring item: " + item2.itemName));
						continue;
					}
					Vector3 position = ((Component)list[num % list.Count]).transform.position;
					SpawnItemAtPosition(item2, position);
					purchasedItems.Remove(item2);
					num++;
				}
			}
			foreach (ItemVolume itemVolume in __instance.itemManager.itemVolumes)
			{
				Object.Destroy((Object)(object)((Component)itemVolume).gameObject);
			}
		}

		private static void SpawnItemAtPosition(Item item, Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = position + SpawnOffset;
			if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobby)
			{
				val = position + SpawnOffsetLobby;
			}
			((Component)ShopManager.instance.itemRotateHelper).transform.parent = ((Component)ShopManager.instance).transform;
			((Component)ShopManager.instance.itemRotateHelper).transform.localRotation = item.spawnRotationOffset;
			Quaternion rotation = ((Component)ShopManager.instance.itemRotateHelper).transform.rotation;
			if (SemiFunc.IsMasterClient())
			{
				PhotonNetwork.InstantiateRoomObject("Items/" + ((Object)item.prefab).name, val, rotation, (byte)0, (object[])null);
			}
			else if (!SemiFunc.IsMultiplayer())
			{
				Object.Instantiate<GameObject>(item.prefab, val, rotation);
			}
		}
	}
}