Decompiled source of MachineControl v0.2.1

BepInEx\plugins\GWYF-MachineControl-BUHE\GWYF-MachineControl-BUHE.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
using Mirror;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[BepInPlugin("com.buhe.gwyfmachinecontrolbuhe", "GWYF-MachineControl-BUHE", "0.2.1")]
public sealed class GwyfMachineControlBuhePlugin : BaseUnityPlugin
{
	private const string DefaultSettingsText = "# GWYF-MachineControl-BUHE\n# 把这个文件放在 GWYF-MachineControl-BUHE.dll 同目录。\n# Enabled: true 开启,false 关闭。\n# PositionsPerFloor: 每一层、每一种机器固定刷几个机位。\n# Machines: 要固定刷的机器英文参数,多个机器用英文逗号隔开。\n# BannedMachines: 禁止随机刷出的机器英文参数,多个机器用英文逗号隔开;留空就是不禁用。\n# 例子:Machines=Crash,DuckRace 且 PositionsPerFloor=2,表示每层 2 个 Crash 机位 + 2 个 DuckRace 机位。\n\nEnabled=true\nPositionsPerFloor=2\nMachines=Crash\nBannedMachines=\n";

	private const string MachineDocText = "GWYF-MachineControl-BUHE 机位参数说明\n\n这个文件只是说明书,不会影响模组效果。\n真正要改的是同目录的:\n  GWYF-MachineControl-BUHE.settings.txt\n\n配置文件示例:\n  Enabled=true\n  PositionsPerFloor=2\n  Machines=Crash,DuckRace\n\n参数说明:\n  Enabled=true\n    开启模组。\n\n  Enabled=false\n    关闭模组。\n\n  PositionsPerFloor=2\n    每一层、每一种机器固定刷 2 个机位。\n    注意:有些机位本身会显示两台机器,所以 2 个机位看起来可能是 4 台机器。\n\n  Machines=Crash\n    每一层固定刷 Crash。\n\n  Machines=Crash,DuckRace\n    每一层固定刷 2 个 Crash 机位,再固定刷 2 个 DuckRace 机位。\n    如果 PositionsPerFloor=1,就变成每层 1 个 Crash + 1 个 DuckRace。\n\n  BannedMachines=\n    不禁用任何机器。\n\n  BannedMachines=DuckRace\n    禁止随机刷出 DuckRace。\n    如果游戏原本随机到了 DuckRace,模组会把它替换成 Machines 里面第一个可用、并且没有被禁用的机器。\n    例如 Machines=Crash 且 BannedMachines=DuckRace,就会把随机到的鸭子赛跑替换成崩溃。\n\n  BannedMachines=DuckRace,Slots\n    禁止随机刷出 DuckRace 和 Slots。\n\n常用机器参数:\n  Crash = 崩溃\n  DuckRace = 鸭子赛跑\n  Slots = 老虎/老虎机\n  Roulette = 轮盘\n  Blackjack = 二十一点\n  Poker = 扑克\n  Baccarat = 百家乐\n  Craps = 骰子\n  CoinFlip = 抛硬币\n  DragonTower = 龙塔\n  HiLoGame = 高低牌\n  Keno = 基诺\n  MoneyWheel = 金钱轮盘\n  Plinko = 弹珠机\n  ClawMachine = 抓娃娃机\n  WheelOfFortune = 幸运转盘\n  BeybladeBattle = 陀螺对战(MoreGames 模组)\n\n填写规则:\n  1. Machines 后面填英文参数,不要填中文名。\n     正确:Machines=Crash,DuckRace\n     错误:Machines=崩溃,鸭子赛跑\n\n  2. 多个机器之间用英文逗号隔开。\n     正确:Crash,DuckRace,Slots\n     错误:Crash,DuckRace,Slots\n\n  3. 改完 GWYF-MachineControl-BUHE.settings.txt 后,重新进一把赌场才会生效。\n\n  4. BannedMachines 也填英文参数,不要填中文名。\n     正确:BannedMachines=DuckRace,Slots\n     错误:BannedMachines=鸭子赛跑,老虎机\n\n  5. 如果某个机器参数当前游戏或当前模组环境里找不到,模组会跳过它,并在 BepInEx 日志里提示。\n";

	internal static GwyfMachineControlBuhePlugin Instance;

	internal static ExternalSettings Settings = ExternalSettings.Default;

	internal static string PluginFolder;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		Instance = this;
		PluginFolder = Path.GetDirectoryName(typeof(GwyfMachineControlBuhePlugin).Assembly.Location);
		EnsureExternalFiles();
		Settings = LoadExternalSettings();
		try
		{
			_harmony = new Harmony("com.buhe.gwyfmachinecontrolbuhe");
			_harmony.PatchAll(typeof(GwyfMachineControlBuhePlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("GWYF-MachineControl-BUHE loaded. PositionsPerFloor=" + Settings.PositionsPerFloor + ", Machines=" + string.Join(",", Settings.Machines.ToArray()) + ", BannedMachines=" + string.Join(",", Settings.BannedMachines.ToArray())));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Failed to install Harmony patches: " + ex));
			_harmony = null;
		}
	}

	private void OnDestroy()
	{
		if (_harmony != null)
		{
			try
			{
				_harmony.UnpatchSelf();
			}
			catch
			{
			}
			_harmony = null;
		}
	}

	internal void LogInfo(string message)
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)message);
	}

	internal void LogWarning(string message)
	{
		((BaseUnityPlugin)this).Logger.LogWarning((object)message);
	}

	internal static ExternalSettings LoadExternalSettings()
	{
		string settingsPath = GetSettingsPath();
		ExternalSettings externalSettings = ExternalSettings.Default;
		try
		{
			if (!File.Exists(settingsPath))
			{
				return externalSettings;
			}
			string[] array = File.ReadAllLines(settingsPath);
			for (int i = 0; i < array.Length; i++)
			{
				string text = StripComment(array[i]).Trim();
				if (text.Length == 0)
				{
					continue;
				}
				int num = text.IndexOf('=');
				if (num <= 0)
				{
					continue;
				}
				string text2 = text.Substring(0, num).Trim();
				string text3 = text.Substring(num + 1).Trim();
				if (text2.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
				{
					if (bool.TryParse(text3, out var result))
					{
						externalSettings.Enabled = result;
					}
				}
				else if (text2.Equals("PositionsPerFloor", StringComparison.OrdinalIgnoreCase))
				{
					if (int.TryParse(text3, out var result2))
					{
						externalSettings.PositionsPerFloor = Math.Max(0, result2);
					}
				}
				else if (text2.Equals("Machines", StringComparison.OrdinalIgnoreCase))
				{
					externalSettings.Machines = ParseMachineList(text3);
				}
				else if (text2.Equals("BannedMachines", StringComparison.OrdinalIgnoreCase))
				{
					externalSettings.BannedMachines = ParseMachineList(text3);
				}
			}
		}
		catch (Exception ex)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.LogWarning("Failed to load external settings, using defaults: " + ex.Message);
			}
		}
		if (externalSettings.Machines.Count == 0)
		{
			externalSettings.Machines.Add("Crash");
		}
		return externalSettings;
	}

	private static string StripComment(string line)
	{
		if (line == null)
		{
			return "";
		}
		int num = line.IndexOf('#');
		int num2 = line.IndexOf("//", StringComparison.Ordinal);
		int num3 = -1;
		if (num >= 0)
		{
			num3 = num;
		}
		if (num2 >= 0 && (num3 < 0 || num2 < num3))
		{
			num3 = num2;
		}
		if (num3 < 0)
		{
			return line;
		}
		return line.Substring(0, num3);
	}

	private static List<string> ParseMachineList(string value)
	{
		List<string> list = new List<string>();
		if (string.IsNullOrEmpty(value))
		{
			return list;
		}
		string[] array = value.Split(new char[1] { ',' });
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (text.Length != 0 && !ContainsIgnoreCase(list, text))
			{
				list.Add(text);
			}
		}
		return list;
	}

	private static bool ContainsIgnoreCase(List<string> values, string value)
	{
		for (int i = 0; i < values.Count; i++)
		{
			if (values[i].Equals(value, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
		}
		return false;
	}

	private static void EnsureExternalFiles()
	{
		try
		{
			string settingsPath = GetSettingsPath();
			if (!File.Exists(settingsPath))
			{
				File.WriteAllText(settingsPath, "# GWYF-MachineControl-BUHE\n# 把这个文件放在 GWYF-MachineControl-BUHE.dll 同目录。\n# Enabled: true 开启,false 关闭。\n# PositionsPerFloor: 每一层、每一种机器固定刷几个机位。\n# Machines: 要固定刷的机器英文参数,多个机器用英文逗号隔开。\n# BannedMachines: 禁止随机刷出的机器英文参数,多个机器用英文逗号隔开;留空就是不禁用。\n# 例子:Machines=Crash,DuckRace 且 PositionsPerFloor=2,表示每层 2 个 Crash 机位 + 2 个 DuckRace 机位。\n\nEnabled=true\nPositionsPerFloor=2\nMachines=Crash\nBannedMachines=\n");
			}
		}
		catch (Exception ex)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.LogWarning("Failed to create external settings file: " + ex.Message);
			}
		}
	}

	internal static string GetSettingsPath()
	{
		return Path.Combine(PluginFolder ?? "", "GWYF-MachineControl-BUHE.settings.txt");
	}
}
internal sealed class ExternalSettings
{
	internal bool Enabled = true;

	internal int PositionsPerFloor = 2;

	internal List<string> Machines = new List<string> { "Crash" };

	internal List<string> BannedMachines = new List<string>();

	internal static ExternalSettings Default => new ExternalSettings();
}
[HarmonyPatch(typeof(StampManager), "PreAssignGamesToStamps")]
internal static class MachineControlPreAssignmentPatch
{
	private static readonly FieldInfo PreAssignedGamesField = AccessTools.Field(typeof(StampManager), "_preAssignedGames");

	private static readonly FieldInfo AllStampsField = AccessTools.Field(typeof(StampManager), "allStamps");

	private static readonly FieldInfo FloorLootTablesField = AccessTools.Field(typeof(StampManager), "floorLootTables");

	private static readonly MethodInfo GetPositionKeyMethod = AccessTools.Method(typeof(StampManager), "GetPositionKey", (Type[])null, (Type[])null);

	[HarmonyPriority(0)]
	private static void Postfix(StampManager __instance)
	{
		if ((Object)(object)__instance == (Object)null || !NetworkServer.active)
		{
			return;
		}
		ExternalSettings externalSettings = (GwyfMachineControlBuhePlugin.Settings = GwyfMachineControlBuhePlugin.LoadExternalSettings());
		if (!externalSettings.Enabled)
		{
			return;
		}
		int num = Math.Max(0, externalSettings.PositionsPerFloor);
		if (num <= 0 || externalSettings.Machines.Count == 0)
		{
			return;
		}
		try
		{
			Dictionary<string, GameObject> dictionary = PreAssignedGamesField.GetValue(__instance) as Dictionary<string, GameObject>;
			IList list = AllStampsField.GetValue(__instance) as IList;
			if (dictionary == null || list == null || dictionary.Count == 0 || list.Count == 0)
			{
				Log("Stamp assignment data is not ready.");
				return;
			}
			Dictionary<string, GameObject> dictionary2 = FindConfiguredPrefabs(__instance, dictionary, externalSettings.Machines);
			if (dictionary2.Count == 0)
			{
				Log("No configured machine prefabs were found. Requested: " + string.Join(",", externalSettings.Machines.ToArray()) + ".");
				return;
			}
			List<ObjectStamp> sortedStamps = CollectSortedStamps(list);
			Dictionary<int, int> totalByFloor = new Dictionary<int, int>();
			Dictionary<int, List<ObjectStamp>> dictionary3 = GroupStampsByFloor(sortedStamps, totalByFloor);
			Dictionary<string, int> dictionary4 = new Dictionary<string, int>();
			HashSet<string> hashSet = new HashSet<string>();
			List<int> list2 = new List<int>(dictionary3.Keys);
			list2.Sort();
			for (int i = 0; i < list2.Count; i++)
			{
				int num2 = list2[i];
				List<ObjectStamp> list3 = dictionary3[num2];
				int num3 = 0;
				for (int j = 0; j < externalSettings.Machines.Count; j++)
				{
					string text = externalSettings.Machines[j];
					if (!dictionary2.TryGetValue(text, out var value))
					{
						continue;
					}
					for (int k = 0; k < num; k++)
					{
						if (num3 >= list3.Count)
						{
							break;
						}
						ObjectStamp stamp = list3[num3++];
						string positionKey = GetPositionKey(__instance, stamp);
						if (!string.IsNullOrEmpty(positionKey) && dictionary.ContainsKey(positionKey))
						{
							dictionary[positionKey] = value;
							hashSet.Add(positionKey);
							Increment(dictionary4, MakeFloorMachineKey(num2, text));
						}
					}
				}
			}
			int bannedReplaced = ReplaceBannedMachines(__instance, sortedStamps, dictionary, hashSet, dictionary2, externalSettings);
			LogFloorSummary(totalByFloor, dictionary4, externalSettings.Machines, num, bannedReplaced);
		}
		catch (Exception ex)
		{
			Log("Machine assignment patch failed: " + ex.GetType().Name + ": " + ex.Message);
		}
	}

	private static List<ObjectStamp> CollectSortedStamps(IList stamps)
	{
		List<ObjectStamp> list = new List<ObjectStamp>();
		for (int i = 0; i < stamps.Count; i++)
		{
			object? obj = stamps[i];
			ObjectStamp val = (ObjectStamp)((obj is ObjectStamp) ? obj : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.Floor != (Object)null)
			{
				list.Add(val);
			}
		}
		list.Sort(delegate(ObjectStamp a, ObjectStamp b)
		{
			//IL_0027: 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_0033: 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)
			int num = a.Floor.floorIndex.CompareTo(b.Floor.floorIndex);
			if (num != 0)
			{
				return num;
			}
			Vector3 position = ((Component)a).transform.position;
			Vector3 position2 = ((Component)b).transform.position;
			int num2 = position.x.CompareTo(position2.x);
			return (num2 != 0) ? num2 : position.z.CompareTo(position2.z);
		});
		return list;
	}

	private static Dictionary<int, List<ObjectStamp>> GroupStampsByFloor(List<ObjectStamp> sortedStamps, Dictionary<int, int> totalByFloor)
	{
		Dictionary<int, List<ObjectStamp>> dictionary = new Dictionary<int, List<ObjectStamp>>();
		for (int i = 0; i < sortedStamps.Count; i++)
		{
			ObjectStamp val = sortedStamps[i];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Floor == (Object)null))
			{
				int floorIndex = val.Floor.floorIndex;
				Increment(totalByFloor, floorIndex);
				if (!dictionary.TryGetValue(floorIndex, out var value))
				{
					value = (dictionary[floorIndex] = new List<ObjectStamp>());
				}
				value.Add(val);
			}
		}
		return dictionary;
	}

	private static int ReplaceBannedMachines(StampManager manager, List<ObjectStamp> sortedStamps, Dictionary<string, GameObject> assigned, HashSet<string> forcedKeys, Dictionary<string, GameObject> prefabByMachine, ExternalSettings settings)
	{
		if (settings.BannedMachines == null || settings.BannedMachines.Count == 0)
		{
			return 0;
		}
		GameObject val = FindBanReplacement(prefabByMachine, settings);
		if ((Object)(object)val == (Object)null)
		{
			Log("BannedMachines is set, but no replacement machine was available. Banned machines will not be replaced.");
			return 0;
		}
		int num = 0;
		for (int i = 0; i < sortedStamps.Count; i++)
		{
			ObjectStamp stamp = sortedStamps[i];
			string positionKey = GetPositionKey(manager, stamp);
			if (!string.IsNullOrEmpty(positionKey) && !forcedKeys.Contains(positionKey) && assigned.ContainsKey(positionKey))
			{
				GameObject prefab = assigned[positionKey];
				if (IsBannedPrefab(prefab, settings.BannedMachines))
				{
					assigned[positionKey] = val;
					num++;
				}
			}
		}
		Log("Banned machine replacement complete. BannedMachines=" + string.Join(",", settings.BannedMachines.ToArray()) + ", replacementPrefab=" + ((Object)val).name + ", replaced=" + num + ".");
		return num;
	}

	private static GameObject FindBanReplacement(Dictionary<string, GameObject> prefabByMachine, ExternalSettings settings)
	{
		for (int i = 0; i < settings.Machines.Count; i++)
		{
			string text = settings.Machines[i];
			if (!ContainsMachine(settings.BannedMachines, text) && prefabByMachine.TryGetValue(text, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
		}
		return null;
	}

	private static bool IsBannedPrefab(GameObject prefab, List<string> bannedMachines)
	{
		if ((Object)(object)prefab == (Object)null || bannedMachines == null)
		{
			return false;
		}
		for (int i = 0; i < bannedMachines.Count; i++)
		{
			if (IsMachinePrefab(prefab, bannedMachines[i]))
			{
				return true;
			}
		}
		return false;
	}

	private static bool ContainsMachine(List<string> machines, string machine)
	{
		if (machines == null)
		{
			return false;
		}
		string text = Normalize(machine);
		for (int i = 0; i < machines.Count; i++)
		{
			if (Normalize(machines[i]) == text)
			{
				return true;
			}
		}
		return false;
	}

	private static void LogFloorSummary(Dictionary<int, int> totalByFloor, Dictionary<string, int> changedByFloorAndMachine, List<string> machines, int perFloorCount, int bannedReplaced)
	{
		List<int> list = new List<int>(totalByFloor.Keys);
		list.Sort();
		int num = 0;
		foreach (int value in changedByFloorAndMachine.Values)
		{
			num += value;
		}
		Log("Machine assignment complete. Requested " + perFloorCount + " positions per machine per floor. Machines=" + string.Join(",", machines.ToArray()) + ". Assigned total: " + num + ". Banned replacements: " + bannedReplaced + ".");
		for (int i = 0; i < list.Count; i++)
		{
			int num2 = list[i];
			List<string> list2 = new List<string>();
			for (int j = 0; j < machines.Count; j++)
			{
				string text = machines[j];
				list2.Add(text + "=" + GetCount(changedByFloorAndMachine, MakeFloorMachineKey(num2, text)));
			}
			Log("Floor " + num2 + ": positions=" + GetCount(totalByFloor, num2) + ", assigned " + string.Join(", ", list2.ToArray()) + ".");
		}
	}

	private static void Increment(Dictionary<int, int> counts, int key)
	{
		counts[key] = GetCount(counts, key) + 1;
	}

	private static int GetCount(Dictionary<int, int> counts, int key)
	{
		if (counts == null || !counts.TryGetValue(key, out var value))
		{
			return 0;
		}
		return value;
	}

	private static void Increment(Dictionary<string, int> counts, string key)
	{
		counts[key] = GetCount(counts, key) + 1;
	}

	private static int GetCount(Dictionary<string, int> counts, string key)
	{
		if (counts == null || !counts.TryGetValue(key, out var value))
		{
			return 0;
		}
		return value;
	}

	private static string MakeFloorMachineKey(int floor, string machine)
	{
		return floor + "|" + Normalize(machine);
	}

	private static string GetPositionKey(StampManager manager, ObjectStamp stamp)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		if (GetPositionKeyMethod == null || (Object)(object)stamp == (Object)null)
		{
			return null;
		}
		object obj = GetPositionKeyMethod.Invoke(manager, new object[2]
		{
			((Component)stamp).transform.position,
			stamp.Floor
		});
		return obj as string;
	}

	private static Dictionary<string, GameObject> FindConfiguredPrefabs(StampManager manager, Dictionary<string, GameObject> assigned, List<string> machines)
	{
		Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
		List<GameObject> catalog = CollectPrefabCatalog(manager, assigned);
		for (int i = 0; i < machines.Count; i++)
		{
			string text = machines[i];
			GameObject val = FindMachinePrefab(catalog, text);
			if ((Object)(object)val != (Object)null)
			{
				dictionary[text] = val;
				Log("Machine key '" + text + "' matched prefab '" + ((Object)val).name + "'.");
			}
			else
			{
				Log("Machine key '" + text + "' was not found in current assignments or floor loot tables.");
			}
		}
		return dictionary;
	}

	private static List<GameObject> CollectPrefabCatalog(StampManager manager, Dictionary<string, GameObject> assigned)
	{
		List<GameObject> list = new List<GameObject>();
		HashSet<GameObject> seen = new HashSet<GameObject>();
		if (assigned != null)
		{
			foreach (GameObject value in assigned.Values)
			{
				AddPrefab(list, seen, value);
			}
		}
		if (!(FloorLootTablesField.GetValue(manager) is IList list2))
		{
			return list;
		}
		for (int i = 0; i < list2.Count; i++)
		{
			object obj = list2[i];
			if (obj != null)
			{
				FieldInfo field = obj.GetType().GetField("lootTable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				object lootTableObject = ((field == null) ? null : field.GetValue(obj));
				AddLootTablePrefabs(list, seen, lootTableObject);
			}
		}
		return list;
	}

	private static void AddLootTablePrefabs(List<GameObject> prefabs, HashSet<GameObject> seen, object lootTableObject)
	{
		if (lootTableObject == null)
		{
			return;
		}
		object memberValue = GetMemberValue(lootTableObject, "LootTable");
		object memberValue2 = GetMemberValue(memberValue, "ObjectsToLoot");
		if (memberValue2 is IList list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				object target = list[i];
				object memberValue3 = GetMemberValue(target, "Loot");
				GameObject prefab = (GameObject)((memberValue3 is GameObject) ? memberValue3 : null);
				AddPrefab(prefabs, seen, prefab);
			}
		}
	}

	private static void AddPrefab(List<GameObject> prefabs, HashSet<GameObject> seen, GameObject prefab)
	{
		if (!((Object)(object)prefab == (Object)null) && !seen.Contains(prefab))
		{
			seen.Add(prefab);
			prefabs.Add(prefab);
		}
	}

	private static GameObject FindMachinePrefab(List<GameObject> catalog, string machine)
	{
		for (int i = 0; i < catalog.Count; i++)
		{
			if (IsMachinePrefab(catalog[i], machine))
			{
				return catalog[i];
			}
		}
		return null;
	}

	private static object GetMemberValue(object target, string name)
	{
		if (target == null)
		{
			return null;
		}
		Type type = target.GetType();
		PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (property != null)
		{
			return property.GetValue(target, null);
		}
		FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			return field.GetValue(target);
		}
		return null;
	}

	private static bool IsMachinePrefab(GameObject prefab, string machine)
	{
		if ((Object)(object)prefab == (Object)null || string.IsNullOrEmpty(machine))
		{
			return false;
		}
		string text = Normalize(machine);
		if (text.Length == 0)
		{
			return false;
		}
		string text2 = Normalize(((Object)prefab).name);
		if (text2 == text || text2.IndexOf(text, StringComparison.Ordinal) >= 0)
		{
			return true;
		}
		GameBase[] componentsInChildren = prefab.GetComponentsInChildren<GameBase>(true);
		foreach (GameBase val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				if (Normalize(((object)val).GetType().Name) == text)
				{
					return true;
				}
				if (Normalize(val.GameName) == text)
				{
					return true;
				}
			}
		}
		Component[] componentsInChildren2 = prefab.GetComponentsInChildren<Component>(true);
		foreach (Component val2 in componentsInChildren2)
		{
			if ((Object)(object)val2 != (Object)null && Normalize(((object)val2).GetType().Name) == text)
			{
				return true;
			}
		}
		return false;
	}

	private static string Normalize(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "";
		}
		char[] array = new char[value.Length];
		int length = 0;
		foreach (char c in value)
		{
			if (char.IsLetterOrDigit(c))
			{
				array[length++] = char.ToLowerInvariant(c);
			}
		}
		return new string(array, 0, length);
	}

	private static void Log(string message)
	{
		if ((Object)(object)GwyfMachineControlBuhePlugin.Instance != (Object)null)
		{
			GwyfMachineControlBuhePlugin.Instance.LogInfo(message);
		}
		else
		{
			Debug.Log((object)("[GWYF-MachineControl-BUHE] " + message));
		}
	}
}