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 NoItemSpawnLimit v1.0.6
NoItemSpawnLimit.dll
Decompiled 5 months agousing 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.5.0")] [assembly: AssemblyInformationalVersion("1.0.5+3875ef4d4834852c19007bde0c9d6483833b20ec")] [assembly: AssemblyProduct("NoItemSpawnLimit")] [assembly: AssemblyTitle("NoItemSpawnLimit")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.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 && !SemiFunc.IsNotMasterClient()) { 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_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Invalid comparison between Unknown and I4 //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0207: 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; Vector3 val2 = (((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobby) ? SpawnOffsetLobby : SpawnOffset); Vector3 position2 = position + val2; SpawnItemAtPosition(item2, position2); 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) ((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(item.prefab.ResourcePath, position, rotation, (byte)0, (object[])null); } else if (!SemiFunc.IsMultiplayer()) { Object.Instantiate<GameObject>(item.prefab.Prefab, position, rotation); } } } }