Decompiled source of Ranensols Woodcutting v1.0.1

Ranensol.BepInEx.Aska.Woodcutting.dll

Decompiled 3 weeks 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.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Ranensol.BepInEx.Aska.Woodcutting.Config;
using Ranensol.BepInEx.Aska.Woodcutting.Models;
using SSSGame;
using SandSailorStudio.Inventory;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Ranensol.BepInEx.Aska.Woodcutting")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1+35193ebffc9aad8b48a1022a74120d61fa0b24c1")]
[assembly: AssemblyProduct("Ranensol Woodcutting")]
[assembly: AssemblyTitle("Ranensol.BepInEx.Aska.Woodcutting")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Ranensol.BepInEx.Aska.Woodcutting
{
	public static class ConfigKeys
	{
		public const string Log = "Log";

		public const string LongStick = "Long Stick";

		public const string Stick = "Stick";

		public const string Bark = "Bark";

		public const string Resin = "Resin";

		public const string Firewood = "Firewood";

		public const string HardwoodLog = "Hardwood Log";

		public const string HardwoodLongStick = "Hardwood Long Stick";

		public const string Thatch = "Thatch";

		public const string BarkFibres = "Fibers";
	}
	public static class ItemNames
	{
		public const string Log = "Item_Wood_RawLog";

		public const string LongStick = "Item_Wood_RawLongStick";

		public const string Stick = "Item_Wood_Sticks";

		public const string Bark = "Item_Wood_Bark";

		public const string Resin = "Item_Wood_Resin";

		public const string Firewood = "Item_Wood_Firewood";

		public const string HardwoodLog = "Item_Wood_HardWoodLog";

		public const string HardwoodLongStick = "Item_Wood_HardWoodLongStick";

		public const string Thatch = "Item_Wood_Thatch";

		public const string BarkFibres = "Item_Wood_BarkFibres";
	}
	[BepInPlugin("Ranensol.BepInEx.Aska.Woodcutting", "Ranensol Woodcutting", "1.0.1")]
	public class Plugin : BasePlugin
	{
		public override void Load()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Ranensol Woodcutting");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.1");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loading...");
			}
			log.LogInfo(val);
			ModConfig modConfig = new ModConfig(((BasePlugin)this).Config, ((BasePlugin)this).Log);
			ManualLogSource log2 = ((BasePlugin)this).Log;
			val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mod Enabled: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(modConfig.ModEnabled);
			}
			log2.LogInfo(val);
			if (!modConfig.ModEnabled)
			{
				ManualLogSource log3 = ((BasePlugin)this).Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(69, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Ranensol Woodcutting");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is DISABLED in config. No patches applied - using vanilla tree loot.");
				}
				log3.LogWarning(val2);
				return;
			}
			ManualLogSource log4 = ((BasePlugin)this).Log;
			val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Verbose Logging: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(modConfig.VerboseLogging);
			}
			log4.LogInfo(val);
			TreeLootSpawner.Initialize(((BasePlugin)this).Log, modConfig);
			new Harmony("Ranensol.BepInEx.Aska.Woodcutting").PatchAll();
			ManualLogSource log5 = ((BasePlugin)this).Log;
			val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Ranensol Woodcutting");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded successfully!");
			}
			log5.LogInfo(val);
		}
	}
	public static class TreeLootSpawner
	{
		private const float SpawnOffsetXZ = 0.3f;

		private const float SpawnOffsetYMin = 0f;

		private const float SpawnOffsetYMax = 3f;

		private const int MaxProcessedSpawners = 1000;

		private static readonly Dictionary<string, ItemInfo> _itemInfoCache = new Dictionary<string, ItemInfo>();

		private static bool _hasSearchedItems = false;

		private static readonly Queue<string> _processedSpawnersQueue = new Queue<string>(1000);

		private static readonly HashSet<string> _processedSpawnersSet = new HashSet<string>();

		private static readonly string[] ValidSpawnerNames = new string[4] { "TrunkSpawner", "StumpSpawner", "harvestSpawner", "HarvestInteraction" };

		public static ModConfig Config { get; private set; }

		public static ManualLogSource Logger { get; private set; }

		public static void Initialize(ManualLogSource logger, ModConfig config)
		{
			Logger = logger;
			Config = config;
		}

		public static bool IsValidSpawnerType(string gameObjName)
		{
			return ValidSpawnerNames.Any((string name) => gameObjName.Equals(name, StringComparison.OrdinalIgnoreCase));
		}

		public static (bool isTrunk, bool isStump, bool isRawWood) DetermineSpawnerType(string gameObjName, string parentName)
		{
			bool item = gameObjName.Equals("TrunkSpawner", StringComparison.OrdinalIgnoreCase) && ModConfig.IsProcessableTrunk(parentName);
			bool item2 = gameObjName.Equals("StumpSpawner", StringComparison.OrdinalIgnoreCase) && ModConfig.IsProcessableStump(parentName);
			bool item3 = (gameObjName.Equals("harvestSpawner", StringComparison.OrdinalIgnoreCase) || gameObjName.Equals("HarvestInteraction", StringComparison.OrdinalIgnoreCase)) && ModConfig.IsProcessableRawWood(parentName);
			return (item, item2, item3);
		}

		public static string CreateSpawnerKey(string parentName, string gameObjName, Vector3 position)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			return $"{parentName}_{gameObjName}_{position.x:F3}_{position.y:F3}_{position.z:F3}";
		}

		public static bool ShouldProcessSpawner(string parentName)
		{
			if (!ModConfig.IsProcessableRawWood(parentName) && !ModConfig.IsProcessableTrunk(parentName))
			{
				return ModConfig.IsProcessableStump(parentName);
			}
			return true;
		}

		public static void MarkSpawnerAsProcessed(string spawnerKey)
		{
			if (_processedSpawnersSet.Add(spawnerKey))
			{
				_processedSpawnersQueue.Enqueue(spawnerKey);
				if (_processedSpawnersQueue.Count > 1000)
				{
					string item = _processedSpawnersQueue.Dequeue();
					_processedSpawnersSet.Remove(item);
				}
			}
		}

		public static bool IsSpawnerAlreadyProcessed(string spawnerKey)
		{
			return _processedSpawnersSet.Contains(spawnerKey);
		}

		public static void SpawnConfiguredLoot(GameObject parentObj, string gameObjName, string parentName, bool isTrunk, bool isRawWood)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			List<LootEntry> lootListForSpawner = GetLootListForSpawner(parentName, isTrunk, isRawWood);
			if (lootListForSpawner == null)
			{
				return;
			}
			if (Config.VerboseLogging)
			{
				ManualLogSource logger = Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Spawning loot for ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(gameObjName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" on ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(parentName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at position ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(parentObj.transform.position);
				}
				logger.LogInfo(val);
			}
			foreach (LootEntry item in lootListForSpawner.Where((LootEntry e) => e.Quantity > 0))
			{
				SpawnLootEntry(parentObj.transform, item.ItemName, item.Quantity);
			}
		}

		private static List<LootEntry> GetLootListForSpawner(string parentName, bool isTrunk, bool isRawWood)
		{
			if (isRawWood)
			{
				return Config.GetConfigForRawWood(parentName)?.Loot;
			}
			TreeLootConfig configForTree = Config.GetConfigForTree(parentName);
			if (configForTree != null)
			{
				if (!isTrunk)
				{
					return configForTree.StumpLoot;
				}
				return configForTree.TrunkLoot;
			}
			return null;
		}

		private static void SpawnLootEntry(Transform spawnTransform, string itemName, int quantity)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			ItemInfo itemInfo = GetItemInfo(itemName);
			bool flag = default(bool);
			if ((Object)(object)itemInfo == (Object)null)
			{
				ManualLogSource logger = Logger;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not find ItemInfo for: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(itemName);
				}
				logger.LogWarning(val);
				return;
			}
			if (Config.ShouldSpawnIndividually(itemName))
			{
				for (int i = 0; i < quantity; i++)
				{
					SpawnItemInWorld(spawnTransform, itemInfo, 1);
				}
				if (Config.VerboseLogging)
				{
					ManualLogSource logger2 = Logger;
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Spawned: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(itemName);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" x");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(quantity);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (individual items)");
					}
					logger2.LogInfo(val2);
				}
				return;
			}
			SpawnItemInWorld(spawnTransform, itemInfo, quantity);
			if (Config.VerboseLogging)
			{
				ManualLogSource logger3 = Logger;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(19, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Spawned: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(itemName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" x");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(quantity);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (stack)");
				}
				logger3.LogInfo(val2);
			}
		}

		private static void SpawnItemInWorld(Transform spawnTransform, ItemInfo itemInfo, int quantity)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(Random.Range(-0.3f, 0.3f), Random.Range(0f, 3f), Random.Range(-0.3f, 0.3f));
			Vector3 val2 = spawnTransform.position + Vector3.up + val;
			Quaternion identity = Quaternion.identity;
			Vector3 one = Vector3.one;
			ItemObjectSpawnContext val3 = (ItemObjectSpawnContext)1;
			itemInfo.SpawnObject(ref val3, ref quantity, ref val2, ref identity, ref one, (Transform)null, true);
		}

		private static ItemInfo GetItemInfo(string itemName)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if (_itemInfoCache.TryGetValue(itemName, out var value))
			{
				return value;
			}
			if (!_hasSearchedItems)
			{
				_hasSearchedItems = true;
				foreach (ItemInfo item in Resources.FindObjectsOfTypeAll<ItemInfo>())
				{
					if (((Object)item).name != null && !_itemInfoCache.ContainsKey(((Object)item).name))
					{
						_itemInfoCache[((Object)item).name] = item;
					}
				}
				if (Config.VerboseLogging)
				{
					ManualLogSource logger = Logger;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cached ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_itemInfoCache.Count);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ItemInfo objects");
					}
					logger.LogInfo(val);
				}
			}
			_itemInfoCache.TryGetValue(itemName, out var value2);
			return value2;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Ranensol.BepInEx.Aska.Woodcutting";

		public const string PLUGIN_NAME = "Ranensol Woodcutting";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace Ranensol.BepInEx.Aska.Woodcutting.Patches
{
	[HarmonyPatch(typeof(SubcomponentSpawner), "Run")]
	public static class SubcomponentSpawnerPostfix
	{
		[HarmonyPostfix]
		private static void Postfix(SubcomponentSpawner __instance)
		{
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			bool flag4 = default(bool);
			try
			{
				if (!TreeLootSpawner.Config.ModEnabled)
				{
					return;
				}
				string name = ((Object)((Component)__instance).gameObject).name;
				if (!TreeLootSpawner.IsValidSpawnerType(name))
				{
					return;
				}
				Transform parent = ((Component)__instance).transform.parent;
				GameObject val = ((parent != null) ? ((Component)parent).gameObject : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				string name2 = ((Object)val).name;
				if (!TreeLootSpawner.ShouldProcessSpawner(name2))
				{
					return;
				}
				var (flag, flag2, flag3) = TreeLootSpawner.DetermineSpawnerType(name, name2);
				if (!flag && !flag2 && !flag3)
				{
					return;
				}
				string spawnerKey = TreeLootSpawner.CreateSpawnerKey(name2, name, val.transform.position);
				if (TreeLootSpawner.IsSpawnerAlreadyProcessed(spawnerKey))
				{
					if (TreeLootSpawner.Config.VerboseLogging)
					{
						ManualLogSource logger = TreeLootSpawner.Logger;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(41, 2, ref flag4);
						if (flag4)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Duplicate spawn attempt detected for ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" on ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name2);
						}
						logger.LogWarning(val2);
					}
				}
				else
				{
					TreeLootSpawner.MarkSpawnerAsProcessed(spawnerKey);
					TreeLootSpawner.SpawnConfiguredLoot(val, name, name2, flag, flag3);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = TreeLootSpawner.Logger;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag4);
				if (flag4)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Error in SubcomponentSpawner postfix: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				logger2.LogError(val3);
			}
		}
	}
	[HarmonyPatch(typeof(SubcomponentSpawner), "Run")]
	public static class SubcomponentSpawnerPrefix
	{
		[HarmonyPrefix]
		private static bool Prefix(SubcomponentSpawner __instance)
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			bool flag4 = default(bool);
			try
			{
				if (!TreeLootSpawner.Config.ModEnabled)
				{
					return true;
				}
				string name = ((Object)((Component)__instance).gameObject).name;
				if (!TreeLootSpawner.IsValidSpawnerType(name))
				{
					return true;
				}
				Transform parent = ((Component)__instance).transform.parent;
				string text = ((parent != null) ? ((Object)((Component)parent).gameObject).name : null) ?? "";
				if (!TreeLootSpawner.ShouldProcessSpawner(text))
				{
					return true;
				}
				var (flag, flag2, flag3) = TreeLootSpawner.DetermineSpawnerType(name, text);
				if (!flag && !flag2 && !flag3)
				{
					return true;
				}
				if (TreeLootSpawner.Config.VerboseLogging)
				{
					ManualLogSource logger = TreeLootSpawner.Logger;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag4);
					if (flag4)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Blocking vanilla spawning for ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" on ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					}
					logger.LogInfo(val);
				}
				return false;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = TreeLootSpawner.Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(37, 1, ref flag4);
				if (flag4)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Error in SubcomponentSpawner prefix: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				logger2.LogError(val2);
				return true;
			}
		}
	}
}
namespace Ranensol.BepInEx.Aska.Woodcutting.Models
{
	public class LootEntry
	{
		public string ItemName { get; init; }

		public int Quantity { get; init; }

		public LootEntry(string itemName, int quantity)
		{
			ItemName = itemName;
			Quantity = quantity;
			base..ctor();
		}
	}
	public class RawWoodLootConfig
	{
		public List<LootEntry> Loot { get; set; } = new List<LootEntry>();

	}
	public class TreeLootConfig
	{
		public List<LootEntry> TrunkLoot { get; set; } = new List<LootEntry>();


		public List<LootEntry> StumpLoot { get; set; } = new List<LootEntry>();

	}
}
namespace Ranensol.BepInEx.Aska.Woodcutting.Config
{
	public class ModConfig
	{
		private readonly ConfigFile _config;

		private readonly ManualLogSource _logger;

		private const string SectionGeneral = "1 - General";

		private const string SectionSpawn = "2 - SpawnMode";

		private const string SectionYoungFirTrunk = "3a - YoungFir.Trunk";

		private const string SectionYoungFirStump = "3b - YoungFir.Stump";

		private const string SectionFirTrunk = "4a - Fir.Trunk";

		private const string SectionFirStump = "4b - Fir.Stump";

		private const string SectionBirchTrunk = "5a - Birch.Trunk";

		private const string SectionBirchStump = "5b - Birch.Stump";

		private const string SectionWillowTrunk = "6a - Willow.Trunk";

		private const string SectionWillowStump = "6b - Willow.Stump";

		private const string RawLogSection = "7a - RawLog";

		private const string RawLongStickSection = "7b - RawLongStick";

		private const string HardwoodLogSection = "8a - HardwoodLog";

		private const string HardwoodLongStickSection = "8b - HardwoodLongStick";

		private readonly Dictionary<string, bool> _spawnIndividually = new Dictionary<string, bool>();

		private TreeLootConfig _firConfig;

		private TreeLootConfig _youngFirConfig;

		private TreeLootConfig _birchConfig;

		private TreeLootConfig _willowConfig;

		private RawWoodLootConfig _rawLogConfig;

		private RawWoodLootConfig _rawLongStickConfig;

		private RawWoodLootConfig _hardwoodLogConfig;

		private RawWoodLootConfig _hardwoodLongStickConfig;

		private static readonly string[] _youngFirTrunks = new string[2] { "Item_Wood_Fir3", "Item_Wood_Fir5" };

		private static readonly string[] _youngFirStumps = new string[3] { "Item_Wood_TreeFir3Sapling", "Harvest_Wood_Fir3", "Harvest_Wood_Fir5" };

		private static readonly string[] _adultFirTrunks = new string[3] { "Item_Wood_Fir1", "Item_Wood_Fir2", "Item_Wood_Fir4" };

		private static readonly string[] _adultFirStumps = new string[1] { "Item_Wood_TreeFir2Sapling" };

		private static readonly string[] _birchTrunks = new string[2] { "Item_Wood_birch1", "Item_Wood_birch2" };

		private static readonly string[] _birchStumps = new string[1] { "Item_Wood_TreeBirch1Sapling" };

		private static readonly string[] _rawWoodPrefixes = new string[4] { "Item_Wood_RawLog", "Item_Wood_RawLongStick", "Item_Wood_HardwoodLog", "Item_Wood_HardWooddLongStick" };

		public bool ModEnabled { get; private set; }

		public bool VerboseLogging { get; private set; }

		public ModConfig(ConfigFile config, ManualLogSource logger)
		{
			_config = config;
			_logger = logger;
			InitializeGeneralConfig();
			InitializeSpawnModeConfig();
			InitializeConfig();
			InitializeRawWoodConfig();
		}

		private void InitializeGeneralConfig()
		{
			_logger.LogInfo((object)"Initializing general configuration...");
			ModEnabled = _config.Bind<bool>("1 - General", "ModEnabled", true, "Enable or disable the entire mod. Set to false to use vanilla loot.").Value;
			VerboseLogging = _config.Bind<bool>("1 - General", "VerboseLogging", false, "Enable detailed logging for every tree/log/longstick harvested. Useful for debugging, but creates a lot of log entries.").Value;
		}

		private void InitializeSpawnModeConfig()
		{
			_logger.LogInfo((object)"Initializing spawn mode configuration...");
			(string, string, bool)[] array = new(string, string, bool)[10]
			{
				("Item_Wood_RawLog", "LogsIndividual", true),
				("Item_Wood_RawLongStick", "LongSticksIndividual", true),
				("Item_Wood_Sticks", "SticksIndividual", true),
				("Item_Wood_Bark", "BarkIndividual", true),
				("Item_Wood_Resin", "ResinIndividual", false),
				("Item_Wood_Firewood", "FirewoodIndividual", true),
				("Item_Wood_HardWoodLog", "HardwoodLogsIndividual", true),
				("Item_Wood_HardWoodLongStick", "HardwoodLongSticksIndividual", true),
				("Item_Wood_Thatch", "ThatchIndividual", true),
				("Item_Wood_BarkFibres", "BarkFibresIndividual", false)
			};
			for (int i = 0; i < array.Length; i++)
			{
				(string, string, bool) tuple = array[i];
				_spawnIndividually[tuple.Item1] = _config.Bind<bool>("2 - SpawnMode", tuple.Item2, tuple.Item3, "Spawn " + tuple.Item1 + " individually (true) or as stacks (false)").Value;
			}
		}

		private void InitializeConfig()
		{
			_logger.LogInfo((object)"Initializing tree loot configuration...");
			_youngFirConfig = new TreeLootConfig
			{
				TrunkLoot = CreateLootList("3a - YoungFir.Trunk", new(string, string, int, string)[8]
				{
					("Log", "Item_Wood_RawLog", 0, "0"),
					("Long Stick", "Item_Wood_RawLongStick", 3, "3"),
					("Stick", "Item_Wood_Sticks", 7, "6"),
					("Bark", "Item_Wood_Bark", 5, "4"),
					("Resin", "Item_Wood_Resin", 10, "3"),
					("Firewood", "Item_Wood_Firewood", 0, "0"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				}),
				StumpLoot = CreateLootList("3b - YoungFir.Stump", new(string, string, int, string)[8]
				{
					("Log", "Item_Wood_RawLog", 0, "0"),
					("Long Stick", "Item_Wood_RawLongStick", 0, "0"),
					("Stick", "Item_Wood_Sticks", 0, "0"),
					("Bark", "Item_Wood_Bark", 2, "0"),
					("Resin", "Item_Wood_Resin", 5, "0"),
					("Firewood", "Item_Wood_Firewood", 5, "2"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
			_firConfig = new TreeLootConfig
			{
				TrunkLoot = CreateLootList("4a - Fir.Trunk", new(string, string, int, string)[8]
				{
					("Log", "Item_Wood_RawLog", 3, "3"),
					("Long Stick", "Item_Wood_RawLongStick", 3, "3"),
					("Stick", "Item_Wood_Sticks", 7, "7"),
					("Bark", "Item_Wood_Bark", 6, "4"),
					("Resin", "Item_Wood_Resin", 30, "3"),
					("Firewood", "Item_Wood_Firewood", 0, "0"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				}),
				StumpLoot = CreateLootList("4b - Fir.Stump", new(string, string, int, string)[8]
				{
					("Log", "Item_Wood_RawLog", 0, "0"),
					("Long Stick", "Item_Wood_RawLongStick", 0, "0"),
					("Stick", "Item_Wood_Sticks", 0, "0"),
					("Bark", "Item_Wood_Bark", 4, "0"),
					("Resin", "Item_Wood_Resin", 15, "0"),
					("Firewood", "Item_Wood_Firewood", 10, "10"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
			_birchConfig = new TreeLootConfig
			{
				TrunkLoot = CreateLootList("5a - Birch.Trunk", new(string, string, int, string)[8]
				{
					("Hardwood Log", "Item_Wood_HardWoodLog", 3, "2"),
					("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 4, "3"),
					("Stick", "Item_Wood_Sticks", 6, "6"),
					("Bark", "Item_Wood_Bark", 8, "6"),
					("Resin", "Item_Wood_Resin", 30, "0"),
					("Firewood", "Item_Wood_Firewood", 0, "0"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				}),
				StumpLoot = CreateLootList("5b - Birch.Stump", new(string, string, int, string)[8]
				{
					("Hardwood Log", "Item_Wood_HardWoodLog", 0, "0"),
					("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 0, "0"),
					("Stick", "Item_Wood_Sticks", 0, "0"),
					("Bark", "Item_Wood_Bark", 5, "0"),
					("Resin", "Item_Wood_Resin", 15, "0"),
					("Firewood", "Item_Wood_Firewood", 10, "10"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
			_willowConfig = new TreeLootConfig
			{
				TrunkLoot = CreateLootList("6a - Willow.Trunk", new(string, string, int, string)[8]
				{
					("Hardwood Log", "Item_Wood_HardWoodLog", 9, "5"),
					("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 11, "7"),
					("Stick", "Item_Wood_Sticks", 24, "14"),
					("Bark", "Item_Wood_Bark", 16, "8"),
					("Resin", "Item_Wood_Resin", 100, "0"),
					("Firewood", "Item_Wood_Firewood", 0, "0"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				}),
				StumpLoot = CreateLootList("6b - Willow.Stump", new(string, string, int, string)[8]
				{
					("Hardwood Log", "Item_Wood_HardWoodLog", 0, "0"),
					("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 0, "0"),
					("Stick", "Item_Wood_Sticks", 0, "0"),
					("Bark", "Item_Wood_Bark", 12, "0"),
					("Resin", "Item_Wood_Resin", 50, "0"),
					("Firewood", "Item_Wood_Firewood", 25, "8"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
		}

		private void InitializeRawWoodConfig()
		{
			_logger.LogInfo((object)"Initializing raw wood loot configuration...");
			_rawLogConfig = new RawWoodLootConfig
			{
				Loot = CreateLootList("7a - RawLog", new(string, string, int, string)[6]
				{
					("Stick", "Item_Wood_Sticks", 2, "4"),
					("Bark", "Item_Wood_Bark", 6, "2"),
					("Resin", "Item_Wood_Resin", 10, "0"),
					("Firewood", "Item_Wood_Firewood", 8, "4"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
			_rawLongStickConfig = new RawWoodLootConfig
			{
				Loot = CreateLootList("7b - RawLongStick", new(string, string, int, string)[6]
				{
					("Stick", "Item_Wood_Sticks", 4, "4"),
					("Bark", "Item_Wood_Bark", 4, "2"),
					("Resin", "Item_Wood_Resin", 5, "0"),
					("Firewood", "Item_Wood_Firewood", 4, "2"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
			_hardwoodLogConfig = new RawWoodLootConfig
			{
				Loot = CreateLootList("8a - HardwoodLog", new(string, string, int, string)[6]
				{
					("Stick", "Item_Wood_Sticks", 4, "5"),
					("Bark", "Item_Wood_Bark", 8, "3"),
					("Resin", "Item_Wood_Resin", 10, "0"),
					("Firewood", "Item_Wood_Firewood", 8, "4"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
			_hardwoodLongStickConfig = new RawWoodLootConfig
			{
				Loot = CreateLootList("8b - HardwoodLongStick", new(string, string, int, string)[6]
				{
					("Stick", "Item_Wood_Sticks", 3, "3"),
					("Bark", "Item_Wood_Bark", 6, "3"),
					("Resin", "Item_Wood_Resin", 5, "0"),
					("Firewood", "Item_Wood_Firewood", 6, "4"),
					("Thatch", "Item_Wood_Thatch", 0, "0"),
					("Fibers", "Item_Wood_BarkFibres", 0, "0")
				})
			};
		}

		private List<LootEntry> CreateLootList(string section, (string configKey, string internalName, int defaultValue, string vanillaInfo)[] entries)
		{
			return entries.Select(((string configKey, string internalName, int defaultValue, string vanillaInfo) e) => new LootEntry(e.internalName, _config.Bind<int>(section, e.configKey, e.defaultValue, "Enter 0+, Vanilla: " + e.vanillaInfo).Value)).ToList();
		}

		public TreeLootConfig GetConfigForTree(string parentName)
		{
			if (_youngFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || _youngFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)))
			{
				return _youngFirConfig;
			}
			if (_adultFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || _adultFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || parentName.StartsWith("Harvest_Wood_Fir", StringComparison.OrdinalIgnoreCase))
			{
				return _firConfig;
			}
			if (_birchTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || _birchStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || parentName.StartsWith("Harvest_Wood_birch", StringComparison.OrdinalIgnoreCase))
			{
				return _birchConfig;
			}
			if (!parentName.StartsWith("Item_Wood_Willow", StringComparison.OrdinalIgnoreCase) && !parentName.StartsWith("Harvest_Wood_Willow", StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			return _willowConfig;
		}

		public RawWoodLootConfig GetConfigForRawWood(string parentName)
		{
			if (!parentName.StartsWith("Item_Wood_RawLog", StringComparison.OrdinalIgnoreCase))
			{
				if (!parentName.StartsWith("Item_Wood_RawLongStick", StringComparison.OrdinalIgnoreCase))
				{
					if (!parentName.StartsWith("Item_Wood_HardwoodLog", StringComparison.OrdinalIgnoreCase))
					{
						if (!parentName.StartsWith("Item_Wood_HardWooddLongStick", StringComparison.OrdinalIgnoreCase))
						{
							return null;
						}
						return _hardwoodLongStickConfig;
					}
					return _hardwoodLogConfig;
				}
				return _rawLongStickConfig;
			}
			return _rawLogConfig;
		}

		public static bool IsProcessableRawWood(string parentName)
		{
			return _rawWoodPrefixes.Any((string prefix) => parentName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
		}

		public static bool IsProcessableTrunk(string parentName)
		{
			if (!_youngFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_adultFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_birchTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)))
			{
				return parentName.StartsWith("Item_Wood_Willow", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		public static bool IsProcessableStump(string parentName)
		{
			if (!_youngFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_adultFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_birchStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !parentName.StartsWith("Harvest_Wood_Fir", StringComparison.OrdinalIgnoreCase) && !parentName.StartsWith("Harvest_Wood_birch", StringComparison.OrdinalIgnoreCase))
			{
				return parentName.StartsWith("Harvest_Wood_Willow", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		public bool ShouldSpawnIndividually(string itemName)
		{
			if (_spawnIndividually.TryGetValue(itemName, out var value))
			{
				return value;
			}
			return true;
		}
	}
}