Decompiled source of SpawnPoolControl v0.2.0

SpawnPoolControl.dll

Decompiled 3 weeks ago
using 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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SpawnPoolControl")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+86bb08baf017b172d0300796bf0d2575725e2004")]
[assembly: AssemblyProduct("SpawnPoolControl")]
[assembly: AssemblyTitle("SpawnPoolControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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;
		}
	}
}
public enum CustomSpawnPool_Vine
{
	SpawnControl_Vine = -1,
	SpawnControl_Vine_Tropics = 1,
	SpawnControl_Vine_Roots = 7
}
public enum CustomSpawnPool_MushroomCluster
{
	SpawnControl_MushroomCluster = -1,
	SpawnControl_MushroomCluster_Shore = 0,
	SpawnControl_MushroomCluster_Tropics = 1,
	SpawnControl_MushroomCluster_Roots = 7,
	SpawnControl_MushroomCluster_Mesa = 6
}
public class SpawnPoolConfig
{
	[JsonProperty("clear_default_weights")]
	public bool ClearDefaultWeights { get; set; }

	[JsonProperty("force_allow_duplicates")]
	public bool ForceAllowDuplicates { get; set; }

	[JsonProperty("items")]
	public Dictionary<string, Dictionary<string, int>>? SpawnPoolItems { get; set; }

	[JsonProperty("replacements")]
	public Dictionary<string, string>? SpawnPoolReplacements { get; set; }
}
internal class JsonHandler
{
	public static void Save(SpawnPoolConfig data, string configName)
	{
		try
		{
			ManualLogSource? log = SpawnPoolControlPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Creating folder");
			}
			string text = Path.Combine(Paths.ConfigPath, "SpawnPoolControl");
			Directory.CreateDirectory(text);
			ManualLogSource? log2 = SpawnPoolControlPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"Created folder");
			}
			string text2 = Path.Combine(text, configName + ".json");
			string contents = JsonConvert.SerializeObject((object)data, (Formatting)1);
			ManualLogSource? log3 = SpawnPoolControlPlugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)"Writing file...");
			}
			File.WriteAllText(text2, contents);
			ManualLogSource? log4 = SpawnPoolControlPlugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)("Saved JSON to: " + text2));
			}
		}
		catch (Exception ex)
		{
			ManualLogSource? log5 = SpawnPoolControlPlugin.Log;
			if (log5 != null)
			{
				log5.LogWarning((object)("Error: " + ex.Message));
			}
		}
	}

	public static SpawnPoolConfig? Load(string configName)
	{
		try
		{
			string path = Path.Combine(Paths.ConfigPath, "SpawnPoolControl");
			string text = Path.Combine(path, configName + ".json");
			if (!File.Exists(text))
			{
				ManualLogSource? log = SpawnPoolControlPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Config not found: " + text));
				}
				return null;
			}
			string text2 = File.ReadAllText(text);
			SpawnPoolConfig result = JsonConvert.DeserializeObject<SpawnPoolConfig>(text2);
			ManualLogSource? log2 = SpawnPoolControlPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("Updated pools from config: " + configName + ".json"));
			}
			return result;
		}
		catch (Exception ex)
		{
			ManualLogSource? log3 = SpawnPoolControlPlugin.Log;
			if (log3 != null)
			{
				log3.LogError((object)("Error loading JSON: " + ex.Message));
			}
			return null;
		}
	}
}
[BepInPlugin("sappykun.PEAK_SpawnPoolControl", "PEAK Spawn Pool Control", "0.2.0")]
public class SpawnPoolControlPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(LootData))]
	public static class LootData_PopulateLootData_Patch
	{
		[HarmonyPostfix]
		[HarmonyPatch("PopulateLootData")]
		public static void Postfix()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (referencePool == null || currentPool?.SpawnPoolItems == null)
			{
				return;
			}
			if (currentPool.ClearDefaultWeights)
			{
				LootData.AllSpawnWeightData = new Dictionary<SpawnPool, Dictionary<ushort, int>>();
			}
			foreach (KeyValuePair<string, Dictionary<string, int>> spawnPoolItem in currentPool.SpawnPoolItems)
			{
				foreach (KeyValuePair<string, int> item in spawnPoolItem.Value)
				{
					if (Enum.TryParse<SpawnPool>(item.Key, out SpawnPool result) && itemNameReverseLUT.TryGetValue(spawnPoolItem.Key, out var value))
					{
						LootData.AllSpawnWeightData.TryAdd(result, new Dictionary<ushort, int>());
						LootData.AllSpawnWeightData[result][value] = item.Value;
					}
				}
			}
		}
	}

	[HarmonyPatch(typeof(LootData), "GetRandomItems")]
	public static class Patch_GetRandomItems
	{
		private static void Prefix(ref bool canRepeat)
		{
			if (currentPool != null && currentPool.ForceAllowDuplicates)
			{
				canRepeat = true;
			}
		}
	}

	[HarmonyPatch(typeof(BerryVine))]
	public class BerryVinePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SpawnItems", new Type[] { typeof(List<Transform>) })]
		public static void SpawnItemsPrefix(BerryVine __instance, List<Transform> spawnSpots, Vector2 __state)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			if (currentPool?.SpawnPoolItems == null)
			{
				return;
			}
			Item val = default(Item);
			foreach (KeyValuePair<string, Dictionary<string, int>> spawnPoolItem in currentPool.SpawnPoolItems)
			{
				foreach (KeyValuePair<string, int> item in spawnPoolItem.Value)
				{
					if (Enum.TryParse<CustomSpawnPool_Vine>(item.Key, out var result) && BiomeChecker.CheckBiome(result))
					{
						if (currentPool.ClearDefaultWeights)
						{
							((Spawner)__instance).spawns = new SpawnList();
							((Spawner)__instance).spawns.items = new List<SpawnEntry>();
						}
						if (ItemDatabase.TryGetItem(itemNameReverseLUT[spawnPoolItem.Key], ref val))
						{
							SpawnEntry val2 = new SpawnEntry();
							val2.prefab = ((Component)val).gameObject;
							val2.weight = item.Value;
							((Spawner)__instance).spawns.items.Add(val2);
						}
					}
				}
			}
		}
	}

	[HarmonyPatch(typeof(GroundPlaceSpawner))]
	public class GroundPlaceSpawnerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SpawnItems", new Type[] { typeof(List<Transform>) })]
		public static void SpawnItemsPrefix(GroundPlaceSpawner __instance, List<Transform> spawnSpots)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			if (currentPool?.SpawnPoolItems == null)
			{
				return;
			}
			Item val = default(Item);
			foreach (KeyValuePair<string, Dictionary<string, int>> spawnPoolItem in currentPool.SpawnPoolItems)
			{
				foreach (KeyValuePair<string, int> item in spawnPoolItem.Value)
				{
					if (Enum.TryParse<CustomSpawnPool_MushroomCluster>(item.Key, out var result) && BiomeChecker.CheckBiome(result))
					{
						if (currentPool.ClearDefaultWeights)
						{
							((Spawner)__instance).spawns = new SpawnList();
							((Spawner)__instance).spawns.items = new List<SpawnEntry>();
						}
						if (ItemDatabase.TryGetItem(itemNameReverseLUT[spawnPoolItem.Key], ref val))
						{
							SpawnEntry val2 = new SpawnEntry();
							val2.prefab = ((Component)val).gameObject;
							val2.weight = item.Value;
							((Spawner)__instance).spawns.items.Add(val2);
						}
					}
				}
			}
		}
	}

	[HarmonyPatch(typeof(SingleItemSpawner))]
	public class SingleItemSpawnerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("TrySpawnItems")]
		public static bool TrySpawnItemsPrefix(SingleItemSpawner __instance)
		{
			if (currentPool?.SpawnPoolReplacements == null)
			{
				return true;
			}
			Item val = default(Item);
			if (currentPool.SpawnPoolReplacements.TryGetValue(((Object)__instance.prefab).name, out string value) && itemNameReverseLUT.TryGetValue(value, out var value2) && ItemDatabase.TryGetItem(value2, ref val))
			{
				__instance.prefab = ((Component)val).gameObject;
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(Spawner), "GetObjectsToSpawn")]
	public static class SpawnerPatch
	{
		private static void Postfix(Spawner __instance, ref List<GameObject> __result)
		{
			if (((object)__instance).GetType().FullName != "Spawner" || currentPool?.SpawnPoolReplacements == null)
			{
				return;
			}
			Item val = default(Item);
			for (int i = 0; i < __result.Count; i++)
			{
				if (currentPool.SpawnPoolReplacements.TryGetValue(((Object)__result[i]).name, out string value) && itemNameReverseLUT.ContainsKey(((Object)__result[i]).name) && itemNameReverseLUT.TryGetValue(value, out var value2) && ItemDatabase.TryGetItem(value2, ref val))
				{
					__result[i] = ((Component)val).gameObject;
				}
			}
		}
	}

	internal static ManualLogSource? Log;

	internal static SpawnPoolConfig? referencePool;

	internal static SpawnPoolConfig? currentPool;

	internal static Dictionary<string, ushort> itemNameReverseLUT = new Dictionary<string, ushort>();

	private ConfigEntry<string>? currentPoolName;

	private void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		Harmony val = new Harmony("sappykun.PEAK_SpawnPoolControl");
		val.PatchAll();
		Log = ((BaseUnityPlugin)this).Logger;
		ManualLogSource? log = Log;
		if (log != null)
		{
			log.LogInfo((object)"Plugin sappykun.PEAK_SpawnPoolControl is loaded!");
		}
		currentPoolName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ConfigName", "", "Name of JSON config file to load (without extensions).");
		currentPoolName.SettingChanged += delegate
		{
			currentPool = JsonHandler.Load(currentPoolName.Value);
			LootData.PopulateLootData();
		};
	}

	private void Start()
	{
		GenerateReferenceConfig();
		if (currentPoolName != null && !(currentPoolName.Value == ""))
		{
			currentPool = JsonHandler.Load(currentPoolName.Value);
			LootData.PopulateLootData();
		}
	}

	private static void GenerateReferenceConfig()
	{
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		if (referencePool != null)
		{
			return;
		}
		itemNameReverseLUT = new Dictionary<string, ushort>();
		LootData.PopulateLootData();
		referencePool = new SpawnPoolConfig
		{
			ClearDefaultWeights = false,
			ForceAllowDuplicates = false,
			SpawnPoolItems = new Dictionary<string, Dictionary<string, int>>(),
			SpawnPoolReplacements = new Dictionary<string, string>()
		};
		foreach (KeyValuePair<ushort, Item> item in SingletonAsset<ItemDatabase>.Instance.itemLookup)
		{
			Dictionary<string, int> value = new Dictionary<string, int>();
			referencePool.SpawnPoolItems.Add(((Object)((Component)item.Value).gameObject).name, value);
			itemNameReverseLUT[((Object)((Component)item.Value).gameObject).name] = item.Key;
			foreach (SpawnPool item2 in Enum.GetValues(typeof(SpawnPool)).Cast<SpawnPool>())
			{
				SpawnPool current2 = item2;
				if (!LootData.AllSpawnWeightData.TryGetValue(current2, out var value2))
				{
					continue;
				}
				foreach (KeyValuePair<ushort, int> item3 in value2)
				{
					if (item.Key == item3.Key)
					{
						referencePool.SpawnPoolItems[((Object)((Component)item.Value).gameObject).name][((object)(SpawnPool)(ref current2)).ToString()] = item3.Value;
					}
				}
			}
		}
		JsonHandler.Save(referencePool, "_reference");
	}
}
public class BiomeChecker
{
	public static bool CheckBiome<TEnum>(TEnum pool)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected I4, but got Unknown
		int currentSegment = Singleton<MapHandler>.Instance.currentSegment;
		int num = (int)Singleton<MapHandler>.Instance.segments[currentSegment].biome;
		int num2 = Convert.ToInt32(pool);
		if (Convert.ToInt32(num2) < 0)
		{
			ManualLogSource? log = SpawnPoolControlPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("Using global override for pool type " + typeof(TEnum).Name));
			}
			return true;
		}
		ManualLogSource? log2 = SpawnPoolControlPlugin.Log;
		if (log2 != null)
		{
			log2.LogDebug((object)$"BiomeChecker: checking value {num2} versus current biome {num}");
		}
		return Convert.ToInt32(num2) == num;
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}