Decompiled source of BreedingUpgradesChickenEggFix v1.1.1

BepInEx/plugins/BreedingUpgradesChickenEggFix/BreedingUpgradesChickenEggFix.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BreedingUpgradesChickenEggFix")]
[assembly: AssemblyDescription("Keeps protected eggs at vanilla quality with BreedingUpgrades")]
[assembly: AssemblyProduct("BreedingUpgradesChickenEggFix")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyVersion("1.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BreedingUpgradesChickenEggFix
{
	[BepInPlugin("local.valheim.breedingupgradeschickeneggfix", "BreedingUpgrades Chicken Egg Fix", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("local.valheim.compatibilityfixes")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private static class BreedingIsEggItemPatch
		{
			public static void Postfix(ItemDrop __0, ref bool __result)
			{
				if (__result && ProtectedEggs.IsProtected(__0))
				{
					__result = false;
				}
			}
		}

		public const string PluginGuid = "local.valheim.breedingupgradeschickeneggfix";

		public const string PluginName = "BreedingUpgrades Chicken Egg Fix";

		public const string PluginVersion = "1.1.1";

		public const string BreedingUpgradesGuid = "dumba.breedingupgrades";

		public const string CombinedPluginGuid = "local.valheim.compatibilityfixes";

		internal static ConfigEntry<bool> FixEnabled;

		internal static ConfigEntry<bool> RepairExistingChickenEggs;

		internal static ConfigEntry<string> AdditionalProtectedEggPrefabs;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			FixEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Fix Enabled", true, "Prevent BreedingUpgrades from creating starred vanilla ChickenEgg items. Asksvin eggs and other eggs are unchanged unless listed below.");
			RepairExistingChickenEggs = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Repair", "Repair Existing Chicken Eggs", true, "Change already-starred protected eggs back to quality 1 when world drops or inventories load/save.");
			AdditionalProtectedEggPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Repair", "Additional Protected Egg Prefabs", string.Empty, "Optional comma- or semicolon-separated prefab names to keep at quality 1 in addition to ChickenEgg. Leave blank for vanilla chickens only.");
			ProtectedEggs.RefreshAdditionalPrefabs(AdditionalProtectedEggPrefabs.Value);
			AdditionalProtectedEggPrefabs.SettingChanged += delegate
			{
				ProtectedEggs.RefreshAdditionalPrefabs(AdditionalProtectedEggPrefabs.Value);
			};
			_harmony = new Harmony("local.valheim.breedingupgradeschickeneggfix");
			_harmony.PatchAll(typeof(ItemDropSetQualityPatch));
			_harmony.PatchAll(typeof(ItemDropLoadPatch));
			_harmony.PatchAll(typeof(InventoryLoadPatch));
			_harmony.PatchAll(typeof(InventorySavePatch));
			InstallBreedingUpgradesEggGate();
			BreedingConsoleCompatibility.Install(_harmony);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded BreedingUpgrades Chicken Egg Fix 1.1.1.");
		}

		private void InstallBreedingUpgradesEggGate()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method("BreedingUpgrades.Patches.ItemDropSetQualityPatch:IsEggItem", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"BreedingUpgrades IsEggItem was not found. The SetQuality failsafe remains active, but BreedingUpgrades may print a cosmetic upgrade message for protected eggs.");
				return;
			}
			HarmonyMethod val = new HarmonyMethod(typeof(BreedingIsEggItemPatch), "Postfix", (Type[])null)
			{
				priority = 0
			};
			_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Installed the BreedingUpgrades vanilla-chicken egg selection gate.");
		}
	}
	internal static class BreedingConsoleCompatibility
	{
		private static readonly string[] CommandNames = new string[3] { "breeding_info", "breeding_simulate", "breeding_debug" };

		private static readonly string[] Descriptions = new string[3] { "Display BreedingUpgrades mod status and configuration", "Simulate breeding rolls. Usage: breeding_simulate [count]", "Toggle debug logging for BreedingUpgrades" };

		private static ConsoleEvent[] _callbacks;

		private static bool _registered;

		internal static void Install(Harmony harmony)
		{
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("BreedingUpgrades.Patches.TerminalPatches");
			if (type == null || type.Assembly.GetName().Version != new Version(1, 0, 2, 0))
			{
				return;
			}
			Type[] array = new Type[12]
			{
				typeof(string),
				typeof(string),
				typeof(ConsoleEvent),
				typeof(bool),
				typeof(bool),
				typeof(bool),
				typeof(bool),
				typeof(bool),
				typeof(ConsoleOptionsFetcher),
				typeof(bool),
				typeof(bool),
				typeof(bool)
			};
			if (AccessTools.Constructor(typeof(ConsoleCommand), array, false) != null)
			{
				return;
			}
			MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "Postfix", Type.EmptyTypes, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(Terminal), "Awake", Type.EmptyTypes, (Type[])null);
			Type nestedType = type.GetNestedType("<>c", BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo fieldInfo = ((nestedType == null) ? null : AccessTools.DeclaredField(nestedType, "<>9"));
			if (methodInfo == null || methodInfo2 == null || fieldInfo == null)
			{
				throw new MissingMethodException("Cannot install the BreedingUpgrades 1.0.2 console compatibility bridge.");
			}
			ConsoleEvent[] array2 = (ConsoleEvent[])(object)new ConsoleEvent[CommandNames.Length];
			object value = fieldInfo.GetValue(null);
			for (int i = 0; i < array2.Length; i++)
			{
				MethodInfo methodInfo3 = AccessTools.DeclaredMethod(nestedType, "<Postfix>b__1_" + i, new Type[1] { typeof(ConsoleEventArgs) }, (Type[])null);
				if (methodInfo3 == null)
				{
					throw new MissingMethodException("Cannot resolve a BreedingUpgrades 1.0.2 console callback.");
				}
				array2[i] = (ConsoleEvent)Delegate.CreateDelegate(typeof(ConsoleEvent), value, methodInfo3);
			}
			_callbacks = array2;
			harmony.Unpatch((MethodBase)methodInfo2, methodInfo);
			harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BreedingConsoleCompatibility), "RegisterCommands", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.Log.LogInfo((object)"Installed the BreedingUpgrades 1.0.2 console bridge for Valheim 1.0.");
		}

		private static void RegisterCommands()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!_registered && _callbacks != null)
			{
				for (int i = 0; i < CommandNames.Length; i++)
				{
					new ConsoleCommand(CommandNames[i], Descriptions[i], _callbacks[i], false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				}
				_registered = true;
			}
		}
	}
	internal static class ProtectedEggs
	{
		private static readonly HashSet<string> ProtectedPrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "ChickenEgg" };

		private static readonly HashSet<string> ChickenEggSharedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "$item_chickenegg", "$item_chicken_egg" };

		internal static void RefreshAdditionalPrefabs(string value)
		{
			ProtectedPrefabNames.Clear();
			ProtectedPrefabNames.Add("ChickenEgg");
			if (!string.IsNullOrWhiteSpace(value))
			{
				string[] array = value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
				for (int i = 0; i < array.Length; i++)
				{
					string text = NormalizePrefabName(array[i]);
					if (!string.IsNullOrEmpty(text))
					{
						ProtectedPrefabNames.Add(text);
					}
				}
			}
			if (Plugin.Log != null)
			{
				Plugin.Log.LogInfo((object)("Protected egg prefabs: " + string.Join(", ", ProtectedPrefabNames)));
			}
		}

		private static string NormalizePrefabName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return string.Empty;
			}
			string text = name.Trim();
			int num = text.IndexOf("(Clone)", StringComparison.OrdinalIgnoreCase);
			if (num >= 0)
			{
				text = text.Substring(0, num).Trim();
			}
			return text;
		}

		private static bool IsProtectedPrefabName(string name)
		{
			return ProtectedPrefabNames.Contains(NormalizePrefabName(name));
		}

		internal static bool IsProtected(ItemDrop itemDrop)
		{
			if (!FeatureEnabled() || (Object)(object)itemDrop == (Object)null)
			{
				return false;
			}
			if (IsProtected(itemDrop.m_itemData))
			{
				return true;
			}
			if ((Object)(object)((Component)itemDrop).gameObject != (Object)null)
			{
				return IsProtectedPrefabName(((Object)((Component)itemDrop).gameObject).name);
			}
			return false;
		}

		internal static bool IsProtected(ItemData item)
		{
			if (!FeatureEnabled() || item == null || item.m_shared == null)
			{
				return false;
			}
			if (ChickenEggSharedNames.Contains(item.m_shared.m_name))
			{
				return true;
			}
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				return IsProtectedPrefabName(((Object)item.m_dropPrefab).name);
			}
			return false;
		}

		private static bool FeatureEnabled()
		{
			if (Plugin.FixEnabled != null)
			{
				return Plugin.FixEnabled.Value;
			}
			return false;
		}

		internal static bool Normalize(ItemData item)
		{
			if (Plugin.RepairExistingChickenEggs != null && Plugin.RepairExistingChickenEggs.Value && IsProtected(item) && item.m_quality != 1)
			{
				item.m_quality = 1;
				return true;
			}
			return false;
		}

		internal static void NormalizeInventory(Inventory inventory)
		{
			if (inventory == null || Plugin.RepairExistingChickenEggs == null || !Plugin.RepairExistingChickenEggs.Value)
			{
				return;
			}
			int num = 0;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (Normalize(allItem))
				{
					num++;
				}
			}
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)("Repaired " + num + " starred protected egg(s) in " + inventory.GetName() + "."));
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "SetQuality", new Type[] { typeof(int) })]
	internal static class ItemDropSetQualityPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "dumba.breedingupgrades" })]
		private static void Prefix(ItemDrop __instance, ref int quality, out bool __state)
		{
			__state = ProtectedEggs.IsProtected(__instance) && ((Plugin.RepairExistingChickenEggs != null && Plugin.RepairExistingChickenEggs.Value) || (!InventoryLoadPatch.IsLoading && (__instance.m_itemData == null || quality != __instance.m_itemData.m_quality)));
			if (__state)
			{
				quality = 1;
			}
		}

		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "dumba.breedingupgrades" })]
		private static void Postfix(ItemDrop __instance, bool __state)
		{
			if (__state && (Object)(object)__instance != (Object)null && ProtectedEggs.IsProtected(__instance) && __instance.m_itemData != null && __instance.m_itemData.m_quality != 1)
			{
				__instance.m_itemData.m_quality = 1;
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "Load", new Type[] { })]
	internal static class ItemDropLoadPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ItemDrop __instance)
		{
			if ((Object)(object)__instance != (Object)null && ProtectedEggs.Normalize(__instance.m_itemData))
			{
				__instance.SetQuality(1);
			}
		}
	}
	[HarmonyPatch]
	internal static class InventoryLoadPatch
	{
		[ThreadStatic]
		private static int _loadDepth;

		internal static bool IsLoading => _loadDepth > 0;

		[HarmonyPrefix]
		private static void Prefix(out bool __state)
		{
			_loadDepth++;
			__state = true;
		}

		[HarmonyFinalizer]
		private static void Finalizer(bool __state)
		{
			if (__state)
			{
				_loadDepth--;
			}
		}

		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type[][] array = new Type[2][]
			{
				new Type[1] { typeof(ZPackage) },
				new Type[2]
				{
					typeof(ZPackage),
					typeof(bool)
				}
			};
			Type[][] array2 = array;
			foreach (Type[] array3 in array2)
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Inventory), "Load", array3, (Type[])null);
				if (methodInfo == null)
				{
					throw new MissingMethodException("Unsupported Valheim Inventory.Load signature; this build requires Valheim 1.0.");
				}
				yield return methodInfo;
			}
		}

		[HarmonyPostfix]
		private static void Postfix(Inventory __instance)
		{
			ProtectedEggs.NormalizeInventory(__instance);
		}
	}
	[HarmonyPatch(typeof(Inventory), "Save", new Type[] { typeof(ZPackage) })]
	internal static class InventorySavePatch
	{
		[HarmonyPrefix]
		private static void Prefix(Inventory __instance)
		{
			ProtectedEggs.NormalizeInventory(__instance);
		}
	}
}