Decompiled source of Control Company Detector v4.0.3

BepInEx/plugins/ControlCompanyDetector.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ControlCompanyDetector.Logic;
using ControlCompanyDetector.Patches;
using HarmonyLib;
using LobbyCompatibility.Attributes;
using LobbyCompatibility.Features;
using LobbyCompatibility.Models;
using Microsoft.CodeAnalysis;
using Steamworks.Data;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace ControlCompanyDetector
{
	[BepInPlugin("JS03.ControlCompanyDetector", "Control Company Detector", "4.0.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[LobbyCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "JS03.ControlCompanyDetector";

		private const string modName = "Control Company Detector";

		private const string modVersion = "4.0.3";

		public static string[] colors;

		public static List<string> keywords;

		public static bool canHostDetectEnemySpawning;

		public static bool clientHasCCFilter;

		public static bool clientHasRBL;

		public static PluginInfo problematicPluginInfo;

		public static ConfigEntry<bool> ignoreFriendlyLobbies;

		public static ConfigEntry<bool> showCCLobbyPrefix;

		public static ConfigEntry<bool> highlightCCLobbies;

		public static ConfigEntry<bool> showControlCompanyLobbiesOnly;

		public static ConfigEntry<bool> hideControlCompanyLobbies;

		public static ConfigEntry<bool> detectEnemySpawning;

		public static ConfigEntry<bool> detectMaskedSpawning;

		public static ConfigEntry<bool> detectEnemySpawningAsHost;

		public static ConfigEntry<string> lobbyHighlightColor;

		public static ConfigEntry<bool> sendChatMessage;

		private readonly Harmony harmony = new Harmony("JS03.ControlCompanyDetector");

		private static Plugin Instance;

		internal static ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			GenerateColors();
			GenerateConfigValues();
			GenerateKeywords();
			mls = Logger.CreateLogSource("JS03.ControlCompanyDetector");
			mls.LogInfo((object)"Control Company Detector has started");
			PatchStuff();
		}

		internal void PatchStuff()
		{
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(LobbyListPatch));
			harmony.PatchAll(typeof(LobbySlotPatch));
			harmony.PatchAll(typeof(RoundManagerPatch));
			harmony.PatchAll(typeof(EnemyVentPatch));
			harmony.PatchAll(typeof(MaskedEnemyPatch));
			harmony.PatchAll(typeof(MenuManagerPatch));
		}

		internal void GenerateConfigValues()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			showCCLobbyPrefix = ((BaseUnityPlugin)this).Config.Bind<bool>("Public Lobbies", "Show CC lobby prefix", true, "Lobbies that are certain to use Control Company will have the [CC] prefix in the lobby list\nNOTE: Challenge moon lobbies that have Control Company will always have the [CC] prefix");
			highlightCCLobbies = ((BaseUnityPlugin)this).Config.Bind<bool>("Public Lobbies", "Highlight Control Company lobbies", true, "Lobbies that are certain to use Control Company will be highlighted in the lobby list");
			lobbyHighlightColor = ((BaseUnityPlugin)this).Config.Bind<string>("Public Lobbies", "Lobby highlight color", "DEFAULT", new ConfigDescription("Changes the color of highlighted lobbies", (AcceptableValueBase)(object)new AcceptableValueList<string>(colors), Array.Empty<object>()));
			hideControlCompanyLobbies = ((BaseUnityPlugin)this).Config.Bind<bool>("Public Lobbies", "Hide Control Company lobbies", false, "Hides lobbies hosting Control Company");
			showControlCompanyLobbiesOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Public Lobbies", "Only show Control Company lobbies", false, "Only shows lobbies hosting Control Company");
			ignoreFriendlyLobbies = ((BaseUnityPlugin)this).Config.Bind<bool>("Private Lobbies", "Ignore friend lobbies", true, "Should the mod completely ignore lobbies created by friends?");
			detectEnemySpawning = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn detection", "Detect enemy spawning", true, "Should the mod be able to detect if an enemy has been spawned by the host? (Only works with indoor enemies)");
			detectMaskedSpawning = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn detection", "Detect Masked enemy spawning", true, "Should the mod be able to detect if a Masked enemy has been spawned by the host?\nDisable this if you're using mods that alter how Masked enemies spawn");
			detectEnemySpawningAsHost = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn detection", "Detect enemy spawning as host", true, "Should the mod be able to detect if an enemy has been spawned by another player when hosting a lobby? (Only works if Detect enemy spawning is enabled)");
			sendChatMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Text Chat", "Send chat message", false, "Sends a message in the chat to let others know when a lobby has Control Company");
		}

		internal static void GenerateKeywords()
		{
			keywords = new List<string> { "BrutalCompany", "HullBreaker", "MoreMonsters", "MonstersPlus", "SavageCompany", "Lethal_Company_Variables", "LethalHoardingSwarm", "TitaniumTurbine.EnemySpawner", "Waffle.MaskedWaves" };
		}

		internal static void GenerateColors()
		{
			colors = new string[12]
			{
				"DEFAULT", "RANDOM", "GREEN", "LIME", "BLUE", "CYAN", "PINK", "PURPLE", "YELLOW", "GRAY",
				"GREY", "MAROON"
			};
		}

		public static void CheckProblematicMods()
		{
			canHostDetectEnemySpawning = true;
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			mls.LogInfo((object)"Getting currently loaded mods...");
			foreach (PluginInfo value in pluginInfos.Values)
			{
				foreach (string keyword in keywords)
				{
					if (value.Metadata.GUID.Contains(keyword))
					{
						mls.LogWarning((object)"A mod that alters how enemies spawn has been detected!");
						canHostDetectEnemySpawning = false;
						problematicPluginInfo = value;
						return;
					}
				}
			}
		}

		public static bool UserHasMod(string modGUID)
		{
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			mls.LogInfo((object)("Checking for " + modGUID + "..."));
			foreach (PluginInfo value in pluginInfos.Values)
			{
				if (value.Metadata.GUID.Equals(modGUID))
				{
					return true;
				}
			}
			return false;
		}

		public static void LogInfoMLS(string info)
		{
			mls.LogInfo((object)info);
		}

		public static void LogWarnMLS(string warn)
		{
			mls.LogWarning((object)warn);
		}
	}
}
namespace ControlCompanyDetector.Patches
{
	[HarmonyPatch(typeof(EnemyVent))]
	internal class EnemyVentPatch
	{
		public static int openVentCount;

		[HarmonyPatch("OpenVentClientRpc")]
		[HarmonyPostfix]
		private static void GetOpenVentCount()
		{
			openVentCount++;
		}
	}
	internal class LobbyListPatch
	{
		[HarmonyPatch(typeof(SteamLobbyManager), "loadLobbyListAndFilter")]
		[HarmonyPrefix]
		private static void FilterLobbyList(ref Lobby[] lobbyList, ref Lobby[] ___currentLobbyList)
		{
			Plugin.clientHasCCFilter = Plugin.UserHasMod("ControlCompany.ControlCompanyFilter");
			Plugin.clientHasRBL = Plugin.UserHasMod("Ryokune.BetterLobbies");
			if (Plugin.hideControlCompanyLobbies.Value)
			{
				List<Lobby> list = ___currentLobbyList.ToList();
				list.RemoveAll(delegate(Lobby lobby)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					LobbyDiff lobbyDiff2 = LobbyHelper.GetLobbyDiff(lobby);
					if (lobbyDiff2.PluginDiffs.Any((PluginDiff diff) => diff.ServerVersion != null))
					{
						return lobbyDiff2.PluginDiffs.Any((PluginDiff diff) => diff.GUID == "ControlCompany.ControlCompany");
					}
					string data2 = ((Lobby)(ref lobby)).GetData("name");
					return data2.Contains('\u200b');
				});
				lobbyList = (___currentLobbyList = list.ToArray());
			}
			else
			{
				if (!Plugin.showControlCompanyLobbiesOnly.Value)
				{
					return;
				}
				List<Lobby> list2 = ___currentLobbyList.ToList();
				list2.RemoveAll(delegate(Lobby lobby)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					LobbyDiff lobbyDiff = LobbyHelper.GetLobbyDiff(lobby);
					if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.ServerVersion != null))
					{
						return !lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.GUID == "ControlCompany.ControlCompany");
					}
					string data = ((Lobby)(ref lobby)).GetData("name");
					bool flag = data.Contains('\u200b');
					return !flag;
				});
				lobbyList = (___currentLobbyList = list2.ToArray());
			}
		}
	}
	[HarmonyPatch(typeof(LobbySlot))]
	internal class LobbySlotPatch
	{
		private static LobbyDiff lobbyDiff;

		private static Color outline;

		private static Color joinHighlight;

		private static Color text;

		private static Color slot;

		private static Color customTextColor;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch(LobbySlot __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				CoroutineManager.StartCoroutine(ModifySlot(__instance));
			}
		}

		internal static IEnumerator ModifySlot(LobbySlot lobbySlot)
		{
			yield return (object)new WaitForEndOfFrame();
			lobbyDiff = LobbyHelper.GetLobbyDiff(lobbySlot.thisLobby);
			AddCCPrefix(lobbySlot);
			if (Plugin.highlightCCLobbies.Value)
			{
				ChangeHighlightColor(Plugin.lobbyHighlightColor.Value);
				CreateCustomSlot(lobbySlot, outline, joinHighlight, text, slot, customTextColor, Plugin.clientHasRBL);
			}
			else
			{
				if (!Plugin.clientHasRBL || !Plugin.clientHasCCFilter)
				{
					yield break;
				}
				RectTransform[] rectTransforms = Object.FindObjectsOfType<RectTransform>();
				RectTransform[] array = rectTransforms;
				foreach (RectTransform rectTransform in array)
				{
					if (((Object)((Component)rectTransform).gameObject).name.Equals("cc"))
					{
						((Transform)rectTransform).localPosition = new Vector3(60f, -12.5f, -7f);
						rectTransform.sizeDelta = new Vector2(220f, 24f);
					}
				}
			}
		}

		internal static void AddCCPrefix(LobbySlot lobbySlot)
		{
			bool flag = ((Object)((Component)lobbySlot).transform).name.Contains("Challenge");
			string data = ((Lobby)(ref lobbySlot.thisLobby)).GetData("name");
			if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.ServerVersion != null))
			{
				if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.GUID == "ControlCompany.ControlCompany"))
				{
					if (flag)
					{
						((TMP_Text)lobbySlot.LobbyName).SetText("[CC] " + data, true);
						return;
					}
					string text = (Plugin.showCCLobbyPrefix.Value ? "[CC] " : "");
					((TMP_Text)lobbySlot.LobbyName).SetText(text + data, true);
				}
			}
			else if (data.Contains('\u200b'))
			{
				if (flag)
				{
					((TMP_Text)lobbySlot.LobbyName).SetText("[CC] " + data, true);
					return;
				}
				string text2 = (Plugin.showCCLobbyPrefix.Value ? "[CC] " : "");
				((TMP_Text)lobbySlot.LobbyName).SetText(text2 + data, true);
			}
		}

		internal static void CreateCustomSlot(LobbySlot lobbySlot, Color outline, Color joinHighlight, Color text, Color slot, Color customTextColor, bool placeLeft)
		{
			if (((Object)((Component)lobbySlot).transform).name.Contains("Challenge"))
			{
				return;
			}
			string data = ((Lobby)(ref lobbySlot.thisLobby)).GetData("name");
			if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.ServerVersion != null))
			{
				if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.GUID == "ControlCompany.ControlCompany"))
				{
					CreateSlotComponents(lobbySlot, placeLeft);
				}
			}
			else if (data.Contains('\u200b'))
			{
				CreateSlotComponents(lobbySlot, placeLeft);
			}
		}

		private static void CreateSlotComponents(LobbySlot lobbySlot, bool placeLeft)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = ((Component)lobbySlot).transform.Find("Outline");
			Image val = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			Transform obj2 = ((Component)lobbySlot).transform.Find("JoinButton/SelectionHighlight");
			Image val2 = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				((Graphic)val).color = outline;
			}
			if (Object.op_Implicit((Object)(object)val2))
			{
				((Graphic)val2).color = joinHighlight;
			}
			TextMeshProUGUI lobbyName = lobbySlot.LobbyName;
			TextMeshProUGUI playerCount = lobbySlot.playerCount;
			((Graphic)lobbyName).color = text;
			((Graphic)playerCount).color = text;
			Image component = ((Component)lobbySlot).GetComponent<Image>();
			((Graphic)component).color = slot;
			Object.Destroy((Object)(object)GameObject.Find("cc"));
			GameObject val3 = new GameObject("CCSlot", new Type[1] { typeof(RectTransform) });
			RectTransform component2 = val3.GetComponent<RectTransform>();
			TextMeshProUGUI val4 = ((Component)component2).gameObject.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val4).fontSize = 21f;
			((TMP_Text)val4).text = "CONTROL COMPANY";
			((TMP_Text)val4).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val4).font = ((TMP_Text)playerCount).font;
			((Graphic)val4).color = customTextColor;
			((Transform)component2).SetParent(((Component)lobbySlot).transform);
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(0f, 1f);
			component2.pivot = new Vector2(0f, 1f);
			((Transform)component2).localScale = new Vector3(0.8497399f, 0.8497399f, 0.8497399f);
			((Transform)component2).localPosition = new Vector3(180f, -15f, -7f);
			if (placeLeft)
			{
				((Transform)component2).localPosition = new Vector3(60f, -15f, -7f);
			}
			component2.sizeDelta = new Vector2(170.5f, 24f);
		}

		private static Color GetColorFromRGBA(float r, float b, float g, float a)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r / 255f, b / 255f, g / 255f, a / 255f);
		}

		internal static void ChangeHighlightColor(string preset)
		{
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_060a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0623: Unknown result type (might be due to invalid IL or missing references)
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Unknown result type (might be due to invalid IL or missing references)
			//IL_067d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0682: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: 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)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_073b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0740: Unknown result type (might be due to invalid IL or missing references)
			//IL_0759: Unknown result type (might be due to invalid IL or missing references)
			//IL_075e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0777: Unknown result type (might be due to invalid IL or missing references)
			//IL_077c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0795: Unknown result type (might be due to invalid IL or missing references)
			//IL_079a: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0718: Unknown result type (might be due to invalid IL or missing references)
			//IL_071d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			if (preset.Equals("RANDOM"))
			{
				int num = Random.Range(2, Plugin.colors.Length);
				preset = Plugin.colors[num];
			}
			switch (preset)
			{
			case "BLUE":
				outline = GetColorFromRGBA(0f, 0f, 255f, 255f);
				joinHighlight = GetColorFromRGBA(50f, 50f, 255f, 255f);
				text = GetColorFromRGBA(100f, 100f, 255f, 255f);
				slot = GetColorFromRGBA(0f, 0f, 125f, 64f);
				customTextColor = GetColorFromRGBA(0f, 0f, 175f, 127f);
				break;
			case "GREEN":
				outline = GetColorFromRGBA(0f, 155f, 0f, 255f);
				joinHighlight = GetColorFromRGBA(0f, 165f, 0f, 255f);
				text = GetColorFromRGBA(0f, 175f, 0f, 255f);
				slot = GetColorFromRGBA(0f, 90f, 0f, 64f);
				customTextColor = GetColorFromRGBA(0f, 120f, 0f, 127f);
				break;
			case "LIME":
				outline = GetColorFromRGBA(0f, 235f, 0f, 235f);
				joinHighlight = GetColorFromRGBA(20f, 235f, 20f, 255f);
				text = GetColorFromRGBA(70f, 235f, 70f, 255f);
				slot = GetColorFromRGBA(0f, 125f, 0f, 64f);
				customTextColor = GetColorFromRGBA(0f, 175f, 0f, 127f);
				break;
			case "CYAN":
				outline = GetColorFromRGBA(0f, 235f, 235f, 235f);
				joinHighlight = GetColorFromRGBA(72f, 235f, 235f, 255f);
				text = GetColorFromRGBA(98f, 235f, 235f, 255f);
				slot = GetColorFromRGBA(0f, 130f, 130f, 64f);
				customTextColor = GetColorFromRGBA(0f, 170f, 170f, 127f);
				break;
			case "PINK":
				outline = GetColorFromRGBA(232f, 136f, 220f, 255f);
				joinHighlight = GetColorFromRGBA(232f, 145f, 222f, 255f);
				text = GetColorFromRGBA(233f, 161f, 223f, 255f);
				slot = GetColorFromRGBA(252f, 156f, 240f, 15f);
				customTextColor = GetColorFromRGBA(252f, 165f, 242f, 63f);
				break;
			case "PURPLE":
				outline = GetColorFromRGBA(255f, 35f, 255f, 255f);
				joinHighlight = GetColorFromRGBA(255f, 85f, 255f, 255f);
				text = GetColorFromRGBA(255f, 90f, 255f, 255f);
				slot = GetColorFromRGBA(145f, 0f, 145f, 64f);
				customTextColor = GetColorFromRGBA(190f, 0f, 190f, 127f);
				break;
			case "YELLOW":
				outline = GetColorFromRGBA(235f, 235f, 0f, 255f);
				joinHighlight = GetColorFromRGBA(235f, 235f, 75f, 255f);
				text = GetColorFromRGBA(235f, 235f, 85f, 255f);
				slot = GetColorFromRGBA(125f, 125f, 0f, 64f);
				customTextColor = GetColorFromRGBA(165f, 165f, 0f, 127f);
				break;
			case "GRAY":
			case "GREY":
				outline = GetColorFromRGBA(128f, 128f, 128f, 255f);
				joinHighlight = GetColorFromRGBA(158f, 158f, 158f, 255f);
				text = GetColorFromRGBA(168f, 168f, 168f, 255f);
				slot = GetColorFromRGBA(75f, 75f, 75f, 64f);
				customTextColor = GetColorFromRGBA(100f, 100f, 100f, 127f);
				break;
			case "MAROON":
				outline = GetColorFromRGBA(158f, 49f, 72f, 255f);
				joinHighlight = GetColorFromRGBA(210f, 0f, 72f, 255f);
				text = GetColorFromRGBA(205f, 71f, 100f, 255f);
				slot = GetColorFromRGBA(158f, 49f, 72f, 64f);
				customTextColor = GetColorFromRGBA(150f, 60f, 89f, 127f);
				break;
			default:
				outline = GetColorFromRGBA(158f, 49f, 72f, 255f);
				joinHighlight = GetColorFromRGBA(210f, 0f, 72f, 255f);
				text = GetColorFromRGBA(205f, 71f, 100f, 255f);
				slot = GetColorFromRGBA(158f, 49f, 72f, 64f);
				customTextColor = GetColorFromRGBA(150f, 60f, 89f, 127f);
				break;
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	internal class MaskedEnemyPatch
	{
		[HarmonyPatch("CreateMimicClientRpc")]
		[HarmonyPostfix]
		private static void CreateMimicPatch()
		{
			RoundManagerPatch.maskDeaths++;
		}
	}
	[HarmonyPatch(typeof(MenuManager))]
	internal class MenuManagerPatch
	{
		[HarmonyPatch("ConfirmHostButton")]
		[HarmonyPrefix]
		private static void CheckIfHostCanDetectEnemySpawning()
		{
			if (Plugin.detectEnemySpawningAsHost.Value)
			{
				Plugin.CheckProblematicMods();
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch : MonoBehaviour
	{
		internal static int enemyCount;

		internal static int previousEnemyCount;

		internal static int previousOpenVentCount;

		public static int maskDeaths;

		internal static int previousMaskDeaths;

		internal static EnemyAI spawnedEnemy;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void DisplayHostOnlyMsg()
		{
			if (!Plugin.canHostDetectEnemySpawning && Plugin.detectEnemySpawningAsHost.Value && ((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				CoroutineManager.StartCoroutine(Detector.SendDelayedUITip("Control Company Detector:", "<size=15>Detect enemy spawning as host has been disabled because you have the following mod installed:</size>\n" + Plugin.problematicPluginInfo.Metadata.Name, warning: false, 3.5f));
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void PatchUpdate()
		{
			if (!((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				if (Detector.canClientDetectEnemySpawning)
				{
					StartSpawnDetection();
				}
			}
			else if (Plugin.detectEnemySpawningAsHost.Value && Plugin.canHostDetectEnemySpawning)
			{
				StartSpawnDetection();
			}
		}

		internal static void StartSpawnDetection()
		{
			if (Plugin.detectEnemySpawning.Value)
			{
				if (!Detector.clientIsFriendsWithHost)
				{
					DetectEnemySpawning();
				}
				else if (((NetworkBehaviour)StartOfRound.Instance).IsHost)
				{
					DetectEnemySpawning();
				}
				else if (!Plugin.ignoreFriendlyLobbies.Value)
				{
					DetectEnemySpawning();
				}
			}
		}

		internal static void DetectEnemySpawning()
		{
			EnemyAI[] array = Object.FindObjectsOfType<EnemyAI>();
			enemyCount = array.Length;
			if (enemyCount > previousEnemyCount)
			{
				spawnedEnemy = array[0];
				DetectIndoorsEnemySpawning();
				previousOpenVentCount = EnemyVentPatch.openVentCount;
			}
			previousEnemyCount = enemyCount;
		}

		internal static void DetectIndoorsEnemySpawning()
		{
			if (IsEnemyTypeValid())
			{
				if (EnemyVentPatch.openVentCount <= previousOpenVentCount)
				{
					DisplayEnemyMessage();
				}
			}
			else if (Plugin.detectMaskedSpawning.Value)
			{
				DetectMaskedEnemySpawning();
			}
		}

		internal static void DetectMaskedEnemySpawning()
		{
			if (((object)spawnedEnemy).GetType() == typeof(MaskedPlayerEnemy) && EnemyVentPatch.openVentCount <= previousOpenVentCount && previousMaskDeaths == maskDeaths)
			{
				DisplayEnemyMessage();
			}
			previousMaskDeaths = maskDeaths;
		}

		internal static void DisplayEnemyMessage()
		{
			Plugin.LogWarnMLS("An enemy has spawned in an abnormal manner");
			if (Detector.hostHasCC)
			{
				Detector.SendUITip("WARNING:", "The host has spawned " + FormatEnemyName(spawnedEnemy, upper: false), warning: false);
			}
			else if (((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				Detector.SendUITip("WARNING:", FormatEnemyName(spawnedEnemy, upper: true) + " has been spawned by a player", warning: false);
			}
		}

		internal static string FormatEnemyName(EnemyAI enemy, bool upper)
		{
			string text = (upper ? "A " : "a ");
			if (((object)enemy).GetType() == typeof(FlowermanAI))
			{
				return text + "Bracken";
			}
			if (((object)enemy).GetType() == typeof(SpringManAI))
			{
				return text + "Coil-Head";
			}
			if (((object)enemy).GetType() == typeof(BlobAI))
			{
				return text + "Hygrodere";
			}
			if (((object)enemy).GetType() == typeof(PufferAI))
			{
				return text + "Spore Lizard";
			}
			if (((object)enemy).GetType() == typeof(CrawlerAI))
			{
				return text + "Thumper";
			}
			if (((object)enemy).GetType() == typeof(HoarderBugAI))
			{
				return (Random.Range(0, 4) == 0) ? (text + "Yippee Bug") : (text + "Hoarding Bug");
			}
			if (((object)enemy).GetType() == typeof(NutcrackerEnemyAI))
			{
				return text + "Nutcracker";
			}
			if (((object)enemy).GetType() == typeof(CentipedeAI))
			{
				return text + "Snare Flea";
			}
			if (((object)enemy).GetType() == typeof(SandSpiderAI))
			{
				return text + "Bunker Spider";
			}
			if (((object)enemy).GetType() == typeof(JesterAI))
			{
				return text + "Jester";
			}
			if (((object)enemy).GetType() == typeof(MaskedPlayerEnemy))
			{
				return text + "Masked Employee";
			}
			if (((object)enemy).GetType() == typeof(LassoManAI))
			{
				return text + "Lasso Man";
			}
			if (((object)enemy).GetType() == typeof(TestEnemy))
			{
				text = (upper ? "An " : "an ");
				return text + "Obunga";
			}
			if (((object)enemy).GetType() == typeof(ButlerEnemyAI))
			{
				return text + "Butler";
			}
			if (((object)enemy).GetType() == typeof(ClaySurgeonAI))
			{
				return text + "Barber";
			}
			if (((object)enemy).GetType() == typeof(CaveDwellerAI))
			{
				return text + "Maneater";
			}
			return text + "[REDACTED]";
		}

		internal static bool IsEnemyTypeValid()
		{
			return ((object)spawnedEnemy).GetType() == typeof(FlowermanAI) || ((object)spawnedEnemy).GetType() == typeof(SpringManAI) || ((object)spawnedEnemy).GetType() == typeof(BlobAI) || ((object)spawnedEnemy).GetType() == typeof(PufferAI) || ((object)spawnedEnemy).GetType() == typeof(CrawlerAI) || ((object)spawnedEnemy).GetType() == typeof(HoarderBugAI) || ((object)spawnedEnemy).GetType() == typeof(NutcrackerEnemyAI) || ((object)spawnedEnemy).GetType() == typeof(CentipedeAI) || ((object)spawnedEnemy).GetType() == typeof(SandSpiderAI) || ((object)spawnedEnemy).GetType() == typeof(JesterAI) || ((object)spawnedEnemy).GetType() == typeof(LassoManAI) || ((object)spawnedEnemy).GetType() == typeof(TestEnemy) || ((object)spawnedEnemy).GetType() == typeof(ButlerEnemyAI) || ((object)spawnedEnemy).GetType() == typeof(ClaySurgeonAI) || ((object)spawnedEnemy).GetType() == typeof(CaveDwellerAI);
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch : MonoBehaviour
	{
		[HarmonyPatch("OnPlayerConnectedClientRpc")]
		[HarmonyPostfix]
		private static void PatchOnPlayerConnected()
		{
			if ((Object)(object)HUDManager.Instance != (Object)null)
			{
				CoroutineManager.StartCoroutine(Detector.StartDetection());
			}
		}
	}
}
namespace ControlCompanyDetector.Logic
{
	public static class CoroutineManager
	{
		internal class CoroutineManagerBehaviour : MonoBehaviour
		{
		}

		private static MonoBehaviour _instance;

		private static MonoBehaviour instance
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = (MonoBehaviour)(object)new GameObject("CoroutineManager").AddComponent<CoroutineManagerBehaviour>();
				}
				return _instance;
			}
		}

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			return instance.StartCoroutine(routine);
		}
	}
	internal static class Detector
	{
		public static bool hostHasCC;

		public static bool clientIsFriendsWithHost;

		public static bool canClientDetectEnemySpawning;

		public static IEnumerator StartDetection()
		{
			Plugin.LogInfoMLS("Checking if host and client are friends...");
			yield return (object)new WaitForSeconds(3.5f);
			clientIsFriendsWithHost = true;
			if (!StartOfRound.Instance.IsClientFriendsWithHost())
			{
				clientIsFriendsWithHost = false;
				Detect();
			}
			else if (!Plugin.ignoreFriendlyLobbies.Value)
			{
				Detect();
			}
		}

		internal static void Detect()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Plugin.LogInfoMLS("Detection started");
			Plugin.LogInfoMLS("Lobby name: " + GameNetworkManager.Instance.steamLobbyName);
			hostHasCC = false;
			canClientDetectEnemySpawning = true;
			if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
			{
				return;
			}
			bool hasValue = GameNetworkManager.Instance.currentLobby.HasValue;
			Plugin.LogInfoMLS("Is the lobby a steam lobby? -> " + hasValue);
			if (!hasValue)
			{
				return;
			}
			LobbyDiff lobbyDiff = LobbyHelper.GetLobbyDiff(GameNetworkManager.Instance.currentLobby.GetValueOrDefault());
			if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.ServerVersion != null))
			{
				if (lobbyDiff.PluginDiffs.Any((PluginDiff diff) => diff.GUID == "ControlCompany.ControlCompany"))
				{
					DisplayWarning();
				}
				{
					foreach (PluginDiff pluginDiff in lobbyDiff.PluginDiffs)
					{
						foreach (string keyword in Plugin.keywords)
						{
							if (pluginDiff.GUID.Contains(keyword))
							{
								canClientDetectEnemySpawning = false;
								Plugin.LogWarnMLS("The host is using a mod that alters enemy spawning!");
								SendUITip("Control Company Detector:", "<size=15>Detect enemy spawning has been disabled because the host has the following mod installed:</size>\n" + pluginDiff.GUID, warning: false);
								return;
							}
						}
					}
					return;
				}
			}
			if (GameNetworkManager.Instance.steamLobbyName.Contains('\u200b'))
			{
				DisplayWarning();
			}
		}

		internal static void DisplayWarning()
		{
			hostHasCC = true;
			Plugin.LogWarnMLS("Control Company has been detected!");
			SendUITip("WARNING:", "The host is using Control Company", warning: true);
			if (Plugin.sendChatMessage.Value)
			{
				HUDManager.Instance.AddTextToChatOnServer("<color=#FF0000>Control Company Detector</color>:<color=#FFFF00> Hey! " + RoundManager.Instance.playersManager.allPlayerScripts[0].playerUsername + " is using Control Company!</color>", -1);
			}
		}

		internal static void SendUITip(string header, string message, bool warning)
		{
			Plugin.LogInfoMLS("Displaying HUD message");
			HUDManager.Instance.DisplayTip(header, message, warning, false, "LC_Tip1");
		}

		public static IEnumerator SendDelayedUITip(string header, string message, bool warning, float delay)
		{
			Plugin.LogInfoMLS("Sending a delayed message...");
			yield return (object)new WaitForSeconds(delay);
			Plugin.LogInfoMLS("Displaying HUD message");
			HUDManager.Instance.DisplayTip(header, message, warning, false, "LC_Tip1");
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}