Decompiled source of MoreGatesExtended v1.0.5

MoreGatesExtended.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Audio;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MoreGatesExtended")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoreGatesExtended")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b890b5fc-3fb7-4e37-8819-3fd25c94ab62")]
[assembly: AssemblyFileVersion("1.0.5")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
namespace MoreGatesExtended;

[BepInPlugin("shudnal.MoreGatesExtended", "More Gates Extended", "1.0.5")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInIncompatibility("hayze.Moregates")]
public class MoreGatesExtended : BaseUnityPlugin
{
	private sealed class RegisteredPiece
	{
		internal CustomPiece CustomPiece;

		internal RequirementConfig[] DefaultRequirements;
	}

	[HarmonyPatch(typeof(AudioMan), "Awake")]
	private static class AudioMan_Awake_AudioRouting
	{
		private static void Postfix(AudioMan __instance)
		{
			if ((Object)(object)__instance == (Object)(object)AudioMan.instance)
			{
				PrefabAudioRouting.Apply(__instance);
			}
		}
	}

	private static class PrefabAudioRouting
	{
		private static readonly HashSet<AudioSource> sources = new HashSet<AudioSource>();

		private static readonly Dictionary<Type, FieldInfo[]> effectFields = new Dictionary<Type, FieldInfo[]>();

		private static AssetBundle collectedBundle;

		private static AudioMixerGroup sfxGroup;

		private static AudioMixer warnedMixer;

		private static bool IsHeadless => (int)SystemInfo.graphicsDeviceType == 4;

		internal static void Collect(AssetBundle bundle, IEnumerable<GameObject> prefabs)
		{
			if ((Object)(object)bundle == (Object)null || prefabs == null || (Object)(object)bundle == (Object)(object)collectedBundle || IsHeadless)
			{
				return;
			}
			try
			{
				HashSet<GameObject> visited = new HashSet<GameObject>();
				foreach (GameObject prefab in prefabs)
				{
					if ((Object)(object)prefab != (Object)null)
					{
						CollectPrefab(prefab, visited, ((Object)prefab).name);
					}
				}
				collectedBundle = bundle;
				LogInfo($"Collected {sources.Count} MoreGates prefab audio source(s).");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)$"Could not collect all MoreGates prefab audio sources: {arg}");
			}
			Apply(AudioMan.instance);
		}

		private static bool IsMock(Transform transform)
		{
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name.StartsWith("JVLmock_", StringComparison.Ordinal) || ((Object)val).name.StartsWith("VLmock_", StringComparison.Ordinal))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void CollectPrefab(GameObject prefab, HashSet<GameObject> visited, string pieceName)
		{
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			if ((Object)(object)prefab == (Object)null || !visited.Add(prefab) || IsMock(prefab.transform))
			{
				return;
			}
			AudioSource[] components = prefab.GetComponents<AudioSource>();
			foreach (AudioSource item in components)
			{
				sources.Add(item);
			}
			int num = 0;
			MonoBehaviour[] components2 = prefab.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components2)
			{
				if ((Object)(object)val == (Object)null)
				{
					num++;
					continue;
				}
				FieldInfo[] array = GetEffectFields(((object)val).GetType());
				foreach (FieldInfo fieldInfo in array)
				{
					object? value = fieldInfo.GetValue(val);
					EffectList val2 = (EffectList)((value is EffectList) ? value : null);
					if (val2?.m_effectPrefabs == null)
					{
						continue;
					}
					EffectData[] effectPrefabs = val2.m_effectPrefabs;
					foreach (EffectData val3 in effectPrefabs)
					{
						if (val3 != null)
						{
							CollectPrefab(val3.m_prefab, visited, pieceName);
						}
					}
				}
			}
			if (num > 0 && loggingEnabled.Value)
			{
				LogInfo("MoreGates piece '" + pieceName + "' references object '" + GetObjectPath(prefab.transform) + "' " + $"with {num} missing script component(s). Audio collection skipped those components; inspect the asset's script references.");
			}
			foreach (Transform item2 in prefab.transform)
			{
				Transform val4 = item2;
				CollectPrefab(((Component)val4).gameObject, visited, pieceName);
			}
		}

		private static string GetObjectPath(Transform transform)
		{
			List<string> list = new List<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				string arg = (string.IsNullOrEmpty(((Object)val).name) ? "<unnamed>" : ((Object)val).name);
				list.Add($"{arg}[{val.GetSiblingIndex()}]");
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list.ToArray());
		}

		private static FieldInfo[] GetEffectFields(Type componentType)
		{
			if (!effectFields.TryGetValue(componentType, out var value))
			{
				List<FieldInfo> list = new List<FieldInfo>();
				Type type = componentType;
				while (type != null && typeof(MonoBehaviour).IsAssignableFrom(type))
				{
					FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (fieldInfo.FieldType == typeof(EffectList))
						{
							list.Add(fieldInfo);
						}
					}
					type = type.BaseType;
				}
				value = list.ToArray();
				effectFields[componentType] = value;
			}
			return value;
		}

		internal static void Apply(AudioMan audioMan)
		{
			if ((Object)(object)instance == (Object)null || (Object)(object)audioMan == (Object)null || (Object)(object)audioMan != (Object)(object)AudioMan.instance || (Object)(object)audioMan.m_masterMixer == (Object)null || sources.Count == 0 || IsHeadless)
			{
				return;
			}
			try
			{
				AudioMixer masterMixer = audioMan.m_masterMixer;
				if ((Object)(object)sfxGroup == (Object)null || (Object)(object)sfxGroup.audioMixer != (Object)(object)masterMixer)
				{
					sfxGroup = ((IEnumerable<AudioMixerGroup>)masterMixer.FindMatchingGroups(string.Empty)).FirstOrDefault((Func<AudioMixerGroup, bool>)((AudioMixerGroup group) => (Object)(object)group != (Object)null && string.Equals(((Object)group).name, "Sfx", StringComparison.OrdinalIgnoreCase)));
				}
				if ((Object)(object)sfxGroup == (Object)null)
				{
					if ((Object)(object)warnedMixer != (Object)(object)masterMixer)
					{
						warnedMixer = masterMixer;
						((BaseUnityPlugin)instance).Logger.LogWarning((object)"Could not find the game's Sfx mixer group; MoreGates prefab audio routing was not changed.");
					}
					return;
				}
				warnedMixer = null;
				sources.RemoveWhere((AudioSource source) => (Object)(object)source == (Object)null);
				int num = 0;
				foreach (AudioSource source in sources)
				{
					if (!((Object)(object)source.outputAudioMixerGroup == (Object)(object)sfxGroup))
					{
						source.outputAudioMixerGroup = sfxGroup;
						num++;
					}
				}
				LogInfo($"Prepared {sources.Count} MoreGates prefab audio source(s); updated {num} Sfx mixer binding(s).");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)$"Could not apply MoreGates prefab audio routing: {arg}");
			}
		}

		internal static void Clear()
		{
			sources.Clear();
			effectFields.Clear();
			collectedBundle = null;
			sfxGroup = null;
			warnedMixer = null;
		}
	}

	[HarmonyPatch(typeof(Destructible), "CreateFragments")]
	internal static class FragmentColliderFix
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Invalid comparison between Unknown and I4
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int index = -1;
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if ((val.opcode == OpCodes.Call || val.opcode == OpCodes.Callvirt) && val.operand is MethodInfo methodInfo && methodInfo.DeclaringType == typeof(GameObject) && methodInfo.Name == "AddComponent" && methodInfo.IsGenericMethod && methodInfo.ReturnType == typeof(BoxCollider) && methodInfo.GetParameters().Length == 0)
				{
					index = i;
					num++;
				}
			}
			if (num != 1)
			{
				Debug.LogWarning((object)("More Gates Extended: expected one BoxCollider creation in Destructible.CreateFragments, " + $"found {num}. The fragment collider fix was not applied."));
				return list;
			}
			CodeInstruction val2 = list[index];
			CodeInstruction val3 = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
			val3.labels.AddRange(val2.labels);
			val2.labels.Clear();
			foreach (ExceptionBlock block in val2.blocks)
			{
				if ((int)block.blockType != 5)
				{
					val3.blocks.Add(block);
				}
			}
			val2.blocks.RemoveAll((ExceptionBlock block) => (int)block.blockType != 5);
			val2.opcode = OpCodes.Call;
			val2.operand = AccessTools.Method(typeof(FragmentColliderFix), "AddFragmentCollider", (Type[])null, (Type[])null);
			list.Insert(index, val3);
			return list;
		}

		private static BoxCollider AddFragmentCollider(GameObject fragment, GameObject sourceRoot)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = fragment.transform;
			Vector3 localScale = transform.localScale;
			if ((!(localScale.x < 0f) && !(localScale.y < 0f) && !(localScale.z < 0f)) || (Object)(object)sourceRoot == (Object)null || (Object)(object)transform.parent != (Object)null)
			{
				return fragment.AddComponent<BoxCollider>();
			}
			Piece componentInParent = sourceRoot.GetComponentInParent<Piece>();
			CustomPiece val = (((Object)(object)componentInParent == (Object)null) ? null : PieceManager.Instance.GetPiece(Utils.GetPrefabName(((Component)componentInParent).gameObject)));
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				BepInPlugin sourceMod = ((CustomEntity)val).SourceMod;
				obj = ((sourceMod != null) ? sourceMod.GUID : null);
			}
			if ((string?)obj != "shudnal.MoreGatesExtended")
			{
				return fragment.AddComponent<BoxCollider>();
			}
			MeshFilter component = fragment.GetComponent<MeshFilter>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
			{
				return fragment.AddComponent<BoxCollider>();
			}
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor((localScale.x < 0f) ? (-1f) : 1f, (localScale.y < 0f) ? (-1f) : 1f, (localScale.z < 0f) ? (-1f) : 1f);
			Bounds bounds = component.sharedMesh.bounds;
			GameObject val3 = new GameObject("MoreGatesFragmentCollider");
			val3.layer = fragment.layer;
			Transform transform2 = val3.transform;
			transform2.SetParent(transform, false);
			transform2.localPosition = Vector3.zero;
			transform2.localRotation = Quaternion.identity;
			transform2.localScale = val2;
			BoxCollider val4 = val3.AddComponent<BoxCollider>();
			val4.center = Vector3.Scale(((Bounds)(ref bounds)).center, val2);
			val4.size = ((Bounds)(ref bounds)).size;
			return val4;
		}
	}

	public const string pluginID = "shudnal.MoreGatesExtended";

	public const string pluginName = "More Gates Extended";

	public const string pluginVersion = "1.0.5";

	private readonly Harmony harmony = new Harmony("shudnal.MoreGatesExtended");

	internal static MoreGatesExtended instance;

	internal static ConfigEntry<bool> loggingEnabled;

	internal static ConfigEntry<string> buildTool;

	internal static ConfigEntry<string> disabledPieces;

	internal static ConfigEntry<string> customRecipes;

	internal static readonly Dictionary<string, string> customRecipesList = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

	internal static HashSet<string> disablePiecesList = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

	internal static AssetBundle bundleFromResources;

	private static readonly Dictionary<string, RegisteredPiece> registeredPieces = new Dictionary<string, RegisteredPiece>(StringComparer.OrdinalIgnoreCase);

	private static bool configurationUpdatePending;

	private static ObjectDB registeredObjectDB;

	private void Awake()
	{
		harmony.PatchAll();
		instance = this;
		ConfigInit();
		Game.isModded = true;
		LoadTranslations();
		FillCustomRecipesAndDisabledPieces();
		PieceManager.OnPiecesRegistered += OnPiecesRegistered;
		SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized;
		RegisterPrefabs();
		RequestConfigurationUpdate();
	}

	private void OnDestroy()
	{
		PieceManager.OnPiecesRegistered -= OnPiecesRegistered;
		SynchronizationManager.OnConfigurationSynchronized -= OnConfigurationSynchronized;
		buildTool.SettingChanged -= OnConfigurationChanged;
		disabledPieces.SettingChanged -= OnConfigurationChanged;
		customRecipes.SettingChanged -= OnConfigurationChanged;
		configurationUpdatePending = false;
		registeredObjectDB = null;
		registeredPieces.Clear();
		PrefabAudioRouting.Clear();
		((BaseUnityPlugin)this).Config.Save();
		instance = null;
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
	}

	internal static void LogInfo(object data)
	{
		if (loggingEnabled.Value)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo(data);
		}
	}

	internal void ConfigInit()
	{
		loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false);
		buildTool = config("General", "Tool", "Hammer", "Identifier of tool to place new objects. This is what is set in PieceTable property of PieceConfig. Changes are applied after configuration synchronization.");
		disabledPieces = config("Pieces", "Disabled pieces", "h_logshort26,h_logshort45,corewood_stack", "Prefab names comma separated case insensitive. Pieces in this list are hidden from the build menu; existing structures remain loadable. Changes are applied after configuration synchronization.");
		customRecipes = config("Pieces", "Custom recipes", "h_drawbridge02:Wood:55:Bronze:8:Chain:4", "Custom pieces recipies, comma separated, starts with prefab name then requirement:amount. \nDefault value is given for example. Changes are applied after configuration synchronization.");
		buildTool.SettingChanged += OnConfigurationChanged;
		disabledPieces.SettingChanged += OnConfigurationChanged;
		customRecipes.SettingChanged += OnConfigurationChanged;
	}

	private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = synchronizedSetting
		} }));
	}

	internal static void LoadTranslations()
	{
		Assembly assembly = typeof(MoreGatesExtended).Assembly;
		string text = typeof(MoreGatesExtended).Namespace + ".translations.";
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		foreach (string item in assembly.GetManifestResourceNames().OrderBy<string, string>((string name) => name, StringComparer.Ordinal))
		{
			if (!item.StartsWith(text, StringComparison.Ordinal) || !item.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
			{
				continue;
			}
			string text2 = item.Substring(text.Length);
			int num = text2.IndexOf('.');
			if (num <= 0)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)("Ignoring localization resource without a language folder: '" + item + "'."));
				continue;
			}
			string text3 = text2.Substring(0, num);
			try
			{
				using Stream stream = assembly.GetManifestResourceStream(item);
				if (stream == null)
				{
					((BaseUnityPlugin)instance).Logger.LogWarning((object)("Could not open localization resource '" + item + "'."));
					continue;
				}
				using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
				localization.AddJsonFile(text3, streamReader.ReadToEnd());
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)$"Could not load localization resource '{item}': {arg}");
			}
		}
	}

	private static void OnConfigurationChanged(object sender, EventArgs args)
	{
		RequestConfigurationUpdate();
	}

	private static void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs args)
	{
		if (!args.InitialSynchronization)
		{
			HashSet<string> updatedPluginGUIDs = args.UpdatedPluginGUIDs;
			if (updatedPluginGUIDs == null || !updatedPluginGUIDs.Contains("shudnal.MoreGatesExtended"))
			{
				return;
			}
		}
		RequestConfigurationUpdate();
	}

	private static void RequestConfigurationUpdate()
	{
		configurationUpdatePending = true;
	}

	private static void OnPiecesRegistered()
	{
		registeredObjectDB = ObjectDB.instance;
		PrefabAudioRouting.Apply(AudioMan.instance);
		RequestConfigurationUpdate();
	}

	private void Update()
	{
		if (configurationUpdatePending && !((Object)(object)registeredObjectDB == (Object)null) && !((Object)(object)registeredObjectDB != (Object)(object)ObjectDB.instance) && ObjectDB.instance.m_items.Count != 0)
		{
			configurationUpdatePending = false;
			ApplyPieceConfiguration();
		}
	}

	internal static void FillCustomRecipesAndDisabledPieces()
	{
		customRecipesList.Clear();
		string[] array = customRecipes.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text in array)
		{
			string text2 = text.Trim();
			int num = text2.IndexOf(':');
			if (num < 1 || string.IsNullOrWhiteSpace(text2.Substring(0, num)))
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)("Ignoring invalid custom recipe entry: '" + text + "'."));
				continue;
			}
			string key = text2.Substring(0, num).Trim();
			customRecipesList[key] = text2.Substring(num + 1);
		}
		disablePiecesList = new HashSet<string>(from name in disabledPieces.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
			select name.Trim() into name
			where name.Length != 0
			select name, StringComparer.OrdinalIgnoreCase);
	}

	private static bool TryParseRequirements(string recipe, out RequirementConfig[] result)
	{
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Expected O, but got Unknown
		List<RequirementConfig> list = new List<RequirementConfig>();
		result = Array.Empty<RequirementConfig>();
		if (string.IsNullOrWhiteSpace(recipe))
		{
			return true;
		}
		string[] array = recipe.Split(new char[1] { ':' });
		if (array.Length % 2 != 0)
		{
			return false;
		}
		for (int i = 0; i < array.Length; i += 2)
		{
			string text = array[i].Trim();
			if (text.Length == 0 || !int.TryParse(array[i + 1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) || result2 < 0)
			{
				return false;
			}
			if (result2 > 0)
			{
				list.Add(new RequirementConfig(text, result2, 0, true));
			}
		}
		result = list.ToArray();
		return true;
	}

	private static bool TryResolveRequirements(RequirementConfig[] requirements, out Requirement[] result)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		result = (Requirement[])(object)new Requirement[requirements.Length];
		for (int i = 0; i < requirements.Length; i++)
		{
			RequirementConfig val = requirements[i];
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(val.Item);
			ItemDrop val2 = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			result[i] = new Requirement
			{
				m_resItem = val2,
				m_amount = val.Amount,
				m_amountPerLevel = val.AmountPerLevel,
				m_recover = val.Recover
			};
		}
		return true;
	}

	private static void ApplyPieceConfiguration()
	{
		FillCustomRecipesAndDisabledPieces();
		string text = (string.IsNullOrWhiteSpace(buildTool.Value) ? "Hammer" : buildTool.Value.Trim());
		PieceTable pieceTable = PieceManager.Instance.GetPieceTable(text);
		if ((Object)(object)pieceTable == (Object)null)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)("Unknown build tool '" + text + "'; using Hammer."));
			text = "Hammer";
			pieceTable = PieceManager.Instance.GetPieceTable(text);
		}
		List<PieceTable> pieceTables = PieceManager.Instance.GetPieceTables();
		foreach (KeyValuePair<string, RegisteredPiece> registeredPiece in registeredPieces)
		{
			RegisteredPiece value = registeredPiece.Value;
			CustomPiece customPiece = value.CustomPiece;
			if ((Object)(object)customPiece.Piece == (Object)null)
			{
				continue;
			}
			customPiece.Piece.m_enabled = !disablePiecesList.Contains(registeredPiece.Key);
			if ((Object)(object)pieceTable != (Object)null)
			{
				foreach (PieceTable item in pieceTables)
				{
					if ((Object)(object)item != (Object)null && ((Object)(object)item != (Object)(object)pieceTable || !customPiece.Piece.m_enabled))
					{
						item.m_pieces.Remove(customPiece.PiecePrefab);
					}
				}
				if (customPiece.Piece.m_enabled && !pieceTable.m_pieces.Contains(customPiece.PiecePrefab))
				{
					pieceTable.m_pieces.Add(customPiece.PiecePrefab);
				}
				customPiece.PieceTable = text;
			}
			RequirementConfig[] defaultRequirements = value.DefaultRequirements;
			if (customRecipesList.TryGetValue(registeredPiece.Key, out var value2))
			{
				if (TryParseRequirements(value2, out var result) && TryResolveRequirements(result, out var result2))
				{
					customPiece.Piece.m_resources = result2;
					continue;
				}
				((BaseUnityPlugin)instance).Logger.LogWarning((object)("Invalid recipe for '" + registeredPiece.Key + "'; using its default requirements."));
			}
			if (TryResolveRequirements(defaultRequirements, out var result3))
			{
				customPiece.Piece.m_resources = result3;
			}
		}
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			Player.m_localPlayer.UpdateAvailablePiecesList();
		}
	}

	private static UsageTagFlags GetUsageTags(string name)
	{
		//IL_060f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0607: Unknown result type (might be due to invalid IL or missing references)
		//IL_0617: Unknown result type (might be due to invalid IL or missing references)
		//IL_061c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0653: Unknown result type (might be due to invalid IL or missing references)
		//IL_0650: Unknown result type (might be due to invalid IL or missing references)
		//IL_0624: Unknown result type (might be due to invalid IL or missing references)
		//IL_062c: Unknown result type (might be due to invalid IL or missing references)
		switch (name)
		{
		case "h_drawbridge01":
		case "h_drawbridge02":
			return (UsageTagFlags)294916;
		case "lift_gate":
		case "lift_gate2":
		case "Hayze_gate_01":
		case "Hayze_gate_02":
		case "Hayze_gate_03":
		case "Hayze_gate_04":
		case "Hayze_gate_05":
		case "Hayze_gate_06":
		case "h_door_01":
		case "h_door_02":
		case "h_door_03":
		case "h_shutter_01":
		case "h_trapdoor":
		case "h_trapdoorbig":
		case "h_trapdoor2":
		case "h_trapdoorbig2":
		case "Hayze_halfgate_01":
		case "Hayze_halfgate_02":
		case "h_window_01":
		case "h_window_02":
		case "h_window_03":
		case "h_window_04":
		case "h_window_05":
		case "h_window_06":
		case "h_window_07":
		case "h_window_08":
		case "h_window_09":
		case "h_window_10":
		case "h_window_11":
		case "h_window_12":
		case "h_window_13":
		case "h_window_14":
			return (UsageTagFlags)262148;
		case "hayzestake_01":
			return (UsageTagFlags)32772;
		case "h_loglong26":
		case "h_loglong45":
		case "h_logshort26":
		case "h_logshort45":
			return (UsageTagFlags)68;
		case "h_chain":
			return (UsageTagFlags)512;
		case "corewood_stack":
			return (UsageTagFlags)65537;
		default:
			((BaseUnityPlugin)instance).Logger.LogWarning((object)("No Hammer usage tags configured for '" + name + "'; using Misc."));
			return (UsageTagFlags)1;
		}
	}

	private static string GetNativeCategory(UsageTagFlags usage)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Invalid comparison between Unknown and I4
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Invalid comparison between Unknown and I4
		if ((usage & 4) > 0)
		{
			return PieceCategories.Building;
		}
		if ((usage & 0x280) > 0)
		{
			return PieceCategories.Furniture;
		}
		return PieceCategories.Misc;
	}

	private static void LoadAsset(string name, RequirementConfig[] requirements)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Expected O, but got Unknown
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		UsageTagFlags usageTags = GetUsageTags(name);
		PieceConfig val = new PieceConfig
		{
			Name = "$piece_mg_" + name,
			PieceTable = "Hammer",
			Category = GetNativeCategory(usageTags),
			Requirements = requirements,
			Description = "$piece_mg_" + name + "_desc",
			CraftingStation = "Workbench"
		};
		LogInfo("Loading MoreGates prefab '" + name + "'.");
		CustomPiece val2 = new CustomPiece(bundleFromResources, name, true, val);
		if ((Object)(object)val2.Piece != (Object)null)
		{
			val2.Piece.m_usage = usageTags;
		}
		if (PieceManager.Instance.AddPiece(val2))
		{
			val2.Piece.m_enabled = !disablePiecesList.Contains(name);
			registeredPieces[name] = new RegisteredPiece
			{
				CustomPiece = val2,
				DefaultRequirements = requirements
			};
		}
	}

	public static void RegisterPrefabs()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Expected O, but got Unknown
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Expected O, but got Unknown
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Expected O, but got Unknown
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Expected O, but got Unknown
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Expected O, but got Unknown
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Expected O, but got Unknown
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Expected O, but got Unknown
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Expected O, but got Unknown
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Expected O, but got Unknown
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Expected O, but got Unknown
		//IL_022c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Expected O, but got Unknown
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Expected O, but got Unknown
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Expected O, but got Unknown
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Expected O, but got Unknown
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Expected O, but got Unknown
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Expected O, but got Unknown
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Expected O, but got Unknown
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Expected O, but got Unknown
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Expected O, but got Unknown
		//IL_0335: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Expected O, but got Unknown
		//IL_0356: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Expected O, but got Unknown
		//IL_0377: Unknown result type (might be due to invalid IL or missing references)
		//IL_037d: Expected O, but got Unknown
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Expected O, but got Unknown
		//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c1: Expected O, but got Unknown
		//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e3: Expected O, but got Unknown
		//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0405: Expected O, but got Unknown
		//IL_0421: Unknown result type (might be due to invalid IL or missing references)
		//IL_0427: Expected O, but got Unknown
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_0449: Expected O, but got Unknown
		//IL_0465: Unknown result type (might be due to invalid IL or missing references)
		//IL_046b: Expected O, but got Unknown
		//IL_0487: Unknown result type (might be due to invalid IL or missing references)
		//IL_048d: Expected O, but got Unknown
		//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04af: Expected O, but got Unknown
		//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d1: Expected O, but got Unknown
		//IL_04db: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e1: Expected O, but got Unknown
		//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0503: Expected O, but got Unknown
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0513: Expected O, but got Unknown
		//IL_052f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0535: Expected O, but got Unknown
		//IL_053f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0545: Expected O, but got Unknown
		//IL_0561: Unknown result type (might be due to invalid IL or missing references)
		//IL_0567: Expected O, but got Unknown
		//IL_0571: Unknown result type (might be due to invalid IL or missing references)
		//IL_0577: Expected O, but got Unknown
		//IL_0593: Unknown result type (might be due to invalid IL or missing references)
		//IL_0599: Expected O, but got Unknown
		//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a9: Expected O, but got Unknown
		//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ca: Expected O, but got Unknown
		//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05eb: Expected O, but got Unknown
		//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fb: Expected O, but got Unknown
		//IL_0616: Unknown result type (might be due to invalid IL or missing references)
		//IL_061c: Expected O, but got Unknown
		//IL_0637: Unknown result type (might be due to invalid IL or missing references)
		//IL_063d: Expected O, but got Unknown
		//IL_0658: Unknown result type (might be due to invalid IL or missing references)
		//IL_065e: Expected O, but got Unknown
		//IL_0679: Unknown result type (might be due to invalid IL or missing references)
		//IL_067f: Expected O, but got Unknown
		//IL_069b: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a1: Expected O, but got Unknown
		bundleFromResources = AssetUtils.LoadAssetBundleFromResources("moregates");
		LoadAsset("h_drawbridge01", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Wood", 60, 0, true),
			new RequirementConfig("Iron", 10, 0, true),
			new RequirementConfig("Chain", 4, 0, true)
		});
		LoadAsset("h_drawbridge02", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Wood", 55, 0, true),
			new RequirementConfig("Bronze", 8, 0, true),
			new RequirementConfig("Chain", 4, 0, true)
		});
		LoadAsset("lift_gate", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Iron", 20, 0, true),
			new RequirementConfig("Stone", 8, 0, true),
			new RequirementConfig("Chain", 4, 0, true)
		});
		LoadAsset("lift_gate2", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Wood", 75, 0, true),
			new RequirementConfig("Bronze", 8, 0, true),
			new RequirementConfig("Chain", 4, 0, true)
		});
		LoadAsset("Hayze_gate_01", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 18, 0, true)
		});
		LoadAsset("Hayze_gate_02", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Wood", 20, 0, true),
			new RequirementConfig("RoundLog", 20, 0, true),
			new RequirementConfig("Bronze", 20, 0, true)
		});
		LoadAsset("Hayze_gate_03", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 15, 0, true)
		});
		LoadAsset("Hayze_gate_04", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 18, 0, true)
		});
		LoadAsset("Hayze_gate_05", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 25, 0, true)
		});
		LoadAsset("Hayze_gate_06", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 18, 0, true),
			new RequirementConfig("IronNails", 3, 0, true)
		});
		LoadAsset("h_door_01", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 5, 0, true)
		});
		LoadAsset("h_door_02", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 6, 0, true)
		});
		LoadAsset("h_door_03", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 6, 0, true)
		});
		LoadAsset("h_shutter_01", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 7, 0, true)
		});
		LoadAsset("h_trapdoor", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 5, 0, true)
		});
		LoadAsset("h_trapdoorbig", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 10, 0, true)
		});
		LoadAsset("h_trapdoor2", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 5, 0, true),
			new RequirementConfig("Iron", 1, 0, true)
		});
		LoadAsset("h_trapdoorbig2", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 10, 0, true),
			new RequirementConfig("Iron", 2, 0, true)
		});
		LoadAsset("Hayze_halfgate_01", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 6, 0, true)
		});
		LoadAsset("Hayze_halfgate_02", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 8, 0, true)
		});
		LoadAsset("h_window_01", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 10, 0, true)
		});
		LoadAsset("h_window_02", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 12, 0, true)
		});
		LoadAsset("h_window_03", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 14, 0, true)
		});
		LoadAsset("h_window_04", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 11, 0, true)
		});
		LoadAsset("h_window_05", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 14, 0, true)
		});
		LoadAsset("h_window_06", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 18, 0, true)
		});
		LoadAsset("h_window_07", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 21, 0, true)
		});
		LoadAsset("h_window_08", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 21, 0, true)
		});
		LoadAsset("h_window_09", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Wood", 21, 0, true)
		});
		LoadAsset("h_window_10", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 21, 0, true),
			new RequirementConfig("Crystal", 1, 0, true)
		});
		LoadAsset("h_window_11", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 21, 0, true),
			new RequirementConfig("Crystal", 1, 0, true)
		});
		LoadAsset("h_window_12", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 21, 0, true),
			new RequirementConfig("Crystal", 1, 0, true)
		});
		LoadAsset("h_window_13", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 21, 0, true),
			new RequirementConfig("Crystal", 1, 0, true)
		});
		LoadAsset("h_window_14", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 21, 0, true),
			new RequirementConfig("Crystal", 1, 0, true)
		});
		LoadAsset("h_chain", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("Chain", 1, 0, true)
		});
		LoadAsset("hayzestake_01", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Wood", 4, 0, true),
			new RequirementConfig("RoundLog", 7, 0, true)
		});
		LoadAsset("h_loglong26", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("RoundLog", 2, 0, true)
		});
		LoadAsset("h_loglong45", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("RoundLog", 2, 0, true)
		});
		LoadAsset("h_logshort26", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("RoundLog", 1, 0, true)
		});
		LoadAsset("h_logshort45", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("RoundLog", 1, 0, true)
		});
		LoadAsset("corewood_stack", (RequirementConfig[])(object)new RequirementConfig[1]
		{
			new RequirementConfig("RoundLog", 50, 0, true)
		});
		PrefabAudioRouting.Collect(bundleFromResources, registeredPieces.Values.Select((RegisteredPiece definition) => definition.CustomPiece.PiecePrefab));
	}
}