Decompiled source of Dvergr Pieces Patch v1.1.0

DvergrPiecesPatch.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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: AssemblyVersion("0.0.0.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 DvergrPiecesPatch
{
	internal static class CustomCategory
	{
		internal const string DisplayName = "Dvergr";

		private static UsageTagFlags flag;

		private static readonly FieldRef<ByUsagePieceList, UsageTagFlags[]> TagsOf = AccessTools.FieldRefAccess<ByUsagePieceList, UsageTagFlags[]>("m_usageTags");

		private static readonly FieldRef<ByUsagePieceList, string[]> NamesOf = AccessTools.FieldRefAccess<ByUsagePieceList, string[]>("m_usageTagDisplayNames");

		internal static UsageTagFlags Flag
		{
			get
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if (!Plugin.CustomCategory.Value)
				{
					return (UsageTagFlags)0;
				}
				return flag;
			}
		}

		internal static void Register(ByUsagePieceList list)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Invalid comparison between I4 and Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected I4, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected I4, but got Unknown
			//IL_004c: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected I4, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.CustomCategory.Value)
			{
				return;
			}
			UsageTagFlags[] array = TagsOf.Invoke(list);
			string[] array2 = NamesOf.Invoke(list);
			if (array == null || array2 == null || array.Length != array2.Length)
			{
				return;
			}
			UsageTagFlags[] array3;
			if ((int)flag == 0)
			{
				int num = 0;
				array3 = array;
				foreach (UsageTagFlags val in array3)
				{
					num |= val;
				}
				int num2 = 1;
				while ((num & num2) != 0)
				{
					num2 <<= 1;
					if (num2 == 0)
					{
						Plugin.Log.LogWarning((object)"No free usage tag bit left - skipping the Dvergr category");
						return;
					}
				}
				flag = (UsageTagFlags)num2;
			}
			array3 = array;
			for (int i = 0; i < array3.Length; i++)
			{
				if ((int)array3[i] == (int)flag)
				{
					return;
				}
			}
			Array.Resize(ref array, array.Length + 1);
			Array.Resize(ref array2, array2.Length + 1);
			array[^1] = (UsageTagFlags)(int)flag;
			array2[^1] = "Dvergr";
			TagsOf.Invoke(list) = array;
			NamesOf.Invoke(list) = array2;
			Plugin.Log.LogInfo((object)("Registered build menu category 'Dvergr' as usage tag " + (int)flag));
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class ByUsagePieceList_Ctor_Patch
	{
		[HarmonyPriority(0)]
		private static void Postfix(ByUsagePieceList __instance)
		{
			CustomCategory.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetScene_Awake_Patch
	{
		private const string ModFermenter = "teq_dv_ferm_fermenter";

		private const string VanillaFermenter = "fermenter";

		private static void Postfix(ZNetScene __instance)
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (!Plugin.FermenterMeads.Value)
			{
				Plugin.Log.LogInfo((object)"Fermenter mead sync disabled by config - brew list left as-is");
				return;
			}
			Fermenter val = FindFermenter(__instance, "teq_dv_ferm_fermenter");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Fermenter val2 = FindFermenter(__instance, "fermenter") ?? BestVanillaGuess(__instance);
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Vanilla fermenter not found - Dvergr fermenter brew list left as-is");
				return;
			}
			if (val.m_conversion == null)
			{
				val.m_conversion = new List<ItemConversion>();
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (ItemConversion item in val.m_conversion)
			{
				if (item != null && (Object)(object)item.m_from != (Object)null)
				{
					hashSet.Add(((Object)item.m_from).name);
				}
			}
			List<string> list = new List<string>();
			foreach (ItemConversion item2 in val2.m_conversion)
			{
				if (item2 != null && !((Object)(object)item2.m_from == (Object)null) && !((Object)(object)item2.m_to == (Object)null) && !hashSet.Contains(((Object)item2.m_from).name))
				{
					val.m_conversion.Add(new ItemConversion
					{
						m_from = item2.m_from,
						m_to = item2.m_to,
						m_producedItems = item2.m_producedItems
					});
					hashSet.Add(((Object)item2.m_from).name);
					list.Add(((Object)item2.m_from).name);
				}
			}
			if (list.Count > 0)
			{
				Plugin.Log.LogInfo((object)("Dvergr fermenter: added " + list.Count + " missing brew(s) from the vanilla fermenter: " + string.Join(", ", list.ToArray())));
			}
			else
			{
				Plugin.Log.LogInfo((object)("Dvergr fermenter: brew list already complete (" + val.m_conversion.Count + " conversions)"));
			}
		}

		private static Fermenter FindFermenter(ZNetScene scene, string prefabName)
		{
			GameObject prefab = scene.GetPrefab(prefabName);
			if (!((Object)(object)prefab == (Object)null))
			{
				return prefab.GetComponent<Fermenter>();
			}
			return null;
		}

		private static Fermenter BestVanillaGuess(ZNetScene scene)
		{
			Fermenter val = null;
			foreach (GameObject prefab in scene.m_prefabs)
			{
				if (!((Object)(object)prefab == (Object)null) && !(((Object)prefab).name == "teq_dv_ferm_fermenter"))
				{
					Fermenter component = prefab.GetComponent<Fermenter>();
					if (!((Object)(object)component == (Object)null) && component.m_conversion != null && ((Object)(object)val == (Object)null || component.m_conversion.Count > val.m_conversion.Count))
					{
						val = component;
					}
				}
			}
			return val;
		}
	}
	internal static class PieceTableFix
	{
		private const string PieceManagerType = "PieceManager.PiecePrefabManager";

		private static FieldRef<PieceTable, List<List<Piece>>> byCategory;

		internal static void Apply(Harmony harmony)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_012c: Expected O, but got Unknown
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "DvergrPieces");
			if (assembly == null)
			{
				Plugin.Log.LogError((object)"DvergrPieces assembly not found - nothing patched.");
				return;
			}
			Type type = assembly.GetType("PieceManager.PiecePrefabManager");
			if (type == null)
			{
				Plugin.Log.LogError((object)"PieceManager.PiecePrefabManager not found in DvergrPieces - nothing patched.");
				return;
			}
			RuntimeHelpers.RunClassConstructor(type.TypeHandle);
			MethodBase methodBase = AccessTools.DeclaredMethod(typeof(PieceTable), "UpdateAvailable", (Type[])null, (Type[])null);
			MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "UpdateAvailable_Prefix", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.DeclaredMethod(type, "UpdateAvailable_Postfix", (Type[])null, (Type[])null);
			if (methodBase == null || methodInfo == null || methodInfo2 == null)
			{
				Plugin.Log.LogError((object)"Could not resolve PieceTable.UpdateAvailable or PieceManager's patches - nothing patched.");
				return;
			}
			byCategory = AccessTools.FieldRefAccess<PieceTable, List<List<Piece>>>("m_availablePiecesByCategory");
			harmony.Unpatch(methodBase, methodInfo);
			harmony.Unpatch(methodBase, methodInfo2);
			harmony.Patch(methodBase, new HarmonyMethod(typeof(PieceTableFix), "Prefix", (Type[])null), new HarmonyMethod(typeof(PieceTableFix), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.Log.LogInfo((object)"Replaced PieceManager's UpdateAvailable prefix/postfix with 1.0-compatible ones");
		}

		private static void Prefix(PieceTable __instance)
		{
			List<List<Piece>> list = byCategory.Invoke(__instance);
			if (list != null && list.Count != 0)
			{
				int num = Enum.GetValues(typeof(PieceCategory)).Length - 1;
				while (list.Count < num)
				{
					list.Add(new List<Piece>());
				}
			}
		}

		private static void Postfix(PieceTable __instance)
		{
			List<List<Piece>> list = byCategory.Invoke(__instance);
			if (list != null)
			{
				Array.Resize(ref __instance.m_selectedPiece, list.Count);
				Array.Resize(ref __instance.m_lastSelectedPiece, list.Count);
			}
		}
	}
	[BepInPlugin("PatTheEvil.DvergrPiecesPatch", "Dvergr Pieces - Valheim 1.0 Patch", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "PatTheEvil.DvergrPiecesPatch";

		public const string NAME = "Dvergr Pieces - Valheim 1.0 Patch";

		public const string VERSION = "1.1.0";

		public const string DvergrPiecesGUID = "Tequila.DvergrPieces";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> CustomCategory;

		internal static ConfigEntry<bool> FermenterMeads;

		private void Awake()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			CustomCategory = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Dvergr category", true, "Show a 'Dvergr' category in the build menu listing every piece of this mod, on top of the vanilla categories each piece already appears under. Takes effect after a restart.");
			FermenterMeads = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Fermenter meads", true, "Let the Dvergr fermenter accept every mead the vanilla fermenter does. Turn this off if you play on a server where not everyone has this patch: a player without it cannot tap a newer mead, and tapping destroys it. Takes effect after a restart.");
			Harmony val = new Harmony("PatTheEvil.DvergrPiecesPatch");
			PieceTableFix.Apply(val);
			val.PatchAll();
		}
	}
	internal static class UsageTags
	{
		internal static readonly Dictionary<string, UsageTagFlags> Map = new Dictionary<string, UsageTagFlags>
		{
			{
				"piece_chest_dvergr_tq",
				(UsageTagFlags)1152
			},
			{
				"piece_chest_dvergr_alt_tq",
				(UsageTagFlags)1152
			},
			{
				"teq_dv_dvergr_shelf",
				(UsageTagFlags)1152
			},
			{
				"blackCoreTorch_tq",
				(UsageTagFlags)256
			},
			{
				"teq_dv_dvergr_lantern",
				(UsageTagFlags)256
			},
			{
				"teq_dv_dvergr_wisp_torch",
				(UsageTagFlags)256
			},
			{
				"teq_dv_ferm_fermenter",
				(UsageTagFlags)2
			},
			{
				"teq_dvergr_door",
				(UsageTagFlags)262144
			},
			{
				"teq_dvergrhead_crown",
				(UsageTagFlags)512
			},
			{
				"teq_dv_vines",
				(UsageTagFlags)512
			},
			{
				"teq_dv_dvergr_bed",
				(UsageTagFlags)128
			},
			{
				"teq_dv_dvergr_table",
				(UsageTagFlags)128
			},
			{
				"teq_dv_dvergr_chair",
				(UsageTagFlags)128
			},
			{
				"teq_dv_dvergr_stool",
				(UsageTagFlags)128
			},
			{
				"teq_dvergr_metal_stairs_left",
				(UsageTagFlags)131072
			},
			{
				"teq_dvergr_metal_stairs_right",
				(UsageTagFlags)131072
			},
			{
				"teq_dv_bm_spiral_left",
				(UsageTagFlags)131072
			},
			{
				"teq_dv_bm_spiral_right",
				(UsageTagFlags)131072
			},
			{
				"teq_dv_wood_stair",
				(UsageTagFlags)131072
			},
			{
				"teq_dv_wood_metal_wall",
				(UsageTagFlags)16
			},
			{
				"teq_dv_wood_metal_wall_alt",
				(UsageTagFlags)16
			},
			{
				"teq_dv_dvergr_wood_floor",
				(UsageTagFlags)8
			},
			{
				"teq_metal_marble_2x2",
				(UsageTagFlags)4
			},
			{
				"teq_dv_wood_metal_pole",
				(UsageTagFlags)68
			},
			{
				"teq_dv_dvergr_wood_beam",
				(UsageTagFlags)68
			},
			{
				"teq_dv_dvergr_wood_beam_med",
				(UsageTagFlags)68
			}
		};

		private static int tagged;

		private static bool reported;

		internal static void Apply(PieceTable table)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)table == (Object)null || table.m_pieces == null)
			{
				return;
			}
			foreach (GameObject piece in table.m_pieces)
			{
				if ((Object)(object)piece == (Object)null)
				{
					continue;
				}
				string text = ((Object)piece).name;
				int num = text.IndexOf("(Clone)");
				if (num >= 0)
				{
					text = text.Substring(0, num);
				}
				if (!Map.TryGetValue(text, out var value))
				{
					continue;
				}
				Piece component = piece.GetComponent<Piece>();
				if (!((Object)(object)component == (Object)null))
				{
					UsageTagFlags val = (UsageTagFlags)(value | CustomCategory.Flag);
					if ((UsageTagFlags)(component.m_usage & val) != val)
					{
						component.m_usage |= val;
						tagged++;
					}
				}
			}
			if (tagged > 0 && !reported)
			{
				reported = true;
				Plugin.Log.LogInfo((object)("Tagged " + tagged + " Dvergr piece(s) for the 1.0 build menu"));
			}
		}
	}
	[HarmonyPatch(typeof(PieceTable), "UpdateAvailable")]
	internal static class PieceTable_UpdateAvailable_Tagging
	{
		private static void Prefix(PieceTable __instance)
		{
			UsageTags.Apply(__instance);
		}
	}
}