Decompiled source of TimerMod v1.2.0

TimerPlugin.dll

Decompiled 5 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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using TMPro;
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: AssemblyCompany("TimerPlugin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("Timer Plugin")]
[assembly: AssemblyTitle("TimerPlugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TimerPlugin
{
	public class TimerPlugin_Config
	{
		private readonly ConfigFile _configFile;

		public static ConfigEntry<bool> configPluginEnabled;

		public static ConfigEntry<bool> configLevelTimerEnabled;

		public static ConfigEntry<bool> configIdleCountdownEnabled;

		public static ConfigEntry<bool> configEnemyTimerEnabled;

		public static ConfigEntry<string> configEnemyShowType;

		public static ConfigEntry<int> configEnemyNameLimit;

		public static ConfigEntry<int> configEnemyTimerPositionX;

		public static ConfigEntry<int> configEnemyTimerPositionY;

		public TimerPlugin_Config(ConfigFile configFile)
		{
			_configFile = configFile;
		}

		public void RegisterOptions()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			configPluginEnabled = _configFile.Bind<bool>("General", "PluginEnabled", true, new ConfigDescription("If enabled, plugin will be loaded", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>()));
			configLevelTimerEnabled = _configFile.Bind<bool>("Timers", "TimerEnabled", true, new ConfigDescription("If enabled, level timer will be shown", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>()));
			configIdleCountdownEnabled = _configFile.Bind<bool>("Timers", "CountdownEnabled", true, new ConfigDescription("If enabled, enemies' idle time will be shown", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>()));
			configEnemyTimerEnabled = _configFile.Bind<bool>("Timers", "EnemyTimerEnabled", true, new ConfigDescription("If enabled, enemies' respawn time will be shown", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>()));
			configEnemyShowType = _configFile.Bind<string>("Timers.Enemy", "EnemyTimerShowType", "ALL", new ConfigDescription("What to show on enemy list\nEnemyList - Shows what enemies are on level\nAlive - Enemy displayed only if it's alive\nDead - Enemy displayed only if it's dead(without time)\nDeadTimer - Shows dead enemies with respawn times\nALL - Shows all info", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "ALL", "Alive", "Dead", "DeadTimer", "EnemyList" }), Array.Empty<object>()));
			configEnemyNameLimit = _configFile.Bind<int>("Timers.Enemy", "EnemyNameLimit", 30, new ConfigDescription("How many characters of enemy name will be dispalyed", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 60), Array.Empty<object>()));
			configEnemyTimerPositionX = _configFile.Bind<int>("Timers.Enemy", "EnemyTimerPositionX", 240, new ConfigDescription("If enabled, enemies' respawn time will be shown", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-500, 500), Array.Empty<object>()));
			configEnemyTimerPositionY = _configFile.Bind<int>("Timers.Enemy", "EnemyTimerPositionY", 85, new ConfigDescription("If enabled, enemies' respawn time will be shown", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-400, 400), Array.Empty<object>()));
		}
	}
	public class EnemyListUI : SemiUI
	{
		private TextMeshProUGUI header;

		public GameObject scanlineObject;

		private TextMeshProUGUI enemyNames;

		private TextMeshProUGUI respawnTimes;

		private float showBigMessage;

		private string enemyToShow;

		private Difficulty difficultyToShow;

		public static EnemyListUI instance;

		private const string colorTier1 = "56FF6D";

		private const string colorTier2 = "FF8D00";

		private const string colorTier3 = "CC0000";

		private Dictionary<Difficulty, string> difficultyColors = new Dictionary<Difficulty, string>
		{
			{
				(Difficulty)0,
				"56FF6D"
			},
			{
				(Difficulty)1,
				"FF8D00"
			},
			{
				(Difficulty)2,
				"CC0000"
			}
		};

		protected override void Start()
		{
			((SemiUI)this).Start();
			instance = this;
			enemyNames = ((Component)((Component)this).transform.Find("EnemyNames")).GetComponent<TextMeshProUGUI>();
			respawnTimes = ((Component)((Component)this).transform.Find("RespawnTimes")).GetComponent<TextMeshProUGUI>();
			header = ((Component)((Component)this).transform.Find("EnemiesHeader")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)enemyNames).text = "";
			((TMP_Text)respawnTimes).text = "";
			((TMP_Text)header).text = "Enemies";
			((TMP_Text)enemyNames).alignment = (TextAlignmentOptions)2052;
			((TMP_Text)enemyNames).enableWordWrapping = false;
			((TMP_Text)enemyNames).overflowMode = (TextOverflowModes)0;
			((TMP_Text)enemyNames).fontStyle = (FontStyles)0;
			((TMP_Text)respawnTimes).alignment = (TextAlignmentOptions)2049;
			((TMP_Text)respawnTimes).enableWordWrapping = false;
			((TMP_Text)respawnTimes).overflowMode = (TextOverflowModes)0;
			((Behaviour)header).enabled = false;
			scanlineObject.SetActive(false);
			UpdatePosition();
			TimerPlugin_Config.configEnemyTimerPositionX.SettingChanged += OnEnemyTimerPositionChanged;
			TimerPlugin_Config.configEnemyTimerPositionY.SettingChanged += OnEnemyTimerPositionChanged;
			if (base.doNotDisable == null)
			{
				base.doNotDisable = new List<GameObject>();
			}
		}

		public string Truncate(string value, int maxChars)
		{
			return (value.Length <= maxChars) ? value : (value.Substring(0, maxChars) + "..");
		}

		private void OnEnemyTimerPositionChanged(object sender, EventArgs e)
		{
			UpdatePosition();
		}

		public void UpdatePosition()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			int value = TimerPlugin_Config.configEnemyTimerPositionX.Value;
			int value2 = TimerPlugin_Config.configEnemyTimerPositionY.Value;
			base.showPosition = new Vector2((float)value, (float)value2);
			if (value >= 0)
			{
				base.hidePosition = new Vector2(600f, (float)value2);
			}
			else
			{
				base.hidePosition = new Vector2(-700f, (float)value2);
			}
		}

		public void Fetch()
		{
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)enemyNames).text = "";
			((TMP_Text)respawnTimes).text = "";
			((Behaviour)header).enabled = false;
			scanlineObject.SetActive(false);
			foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned)
			{
				float despawnedTimer = item.DespawnedTimer;
				bool flag = (double)despawnedTimer <= 1E-06;
				bool flag2 = SemiFunc.IsNotMasterClient();
				if (flag2 && flag)
				{
					flag = item.EnableObject.activeSelf;
				}
				if (flag)
				{
					if (TimerPlugin_Config.configEnemyShowType.Value == "Alive" || TimerPlugin_Config.configEnemyShowType.Value == "EnemyList" || TimerPlugin_Config.configEnemyShowType.Value == "ALL")
					{
						TextMeshProUGUI val = enemyNames;
						((TMP_Text)val).text = ((TMP_Text)val).text + "<color=#" + difficultyColors[item.difficulty] + ">" + Truncate(item.enemyName, TimerPlugin_Config.configEnemyNameLimit.Value) + "</color>\n";
						if (TimerPlugin_Config.configEnemyShowType.Value == "ALL")
						{
							TextMeshProUGUI obj = respawnTimes;
							((TMP_Text)obj).text = ((TMP_Text)obj).text + "<b>Alive</b>\n";
						}
					}
				}
				else
				{
					if (!(TimerPlugin_Config.configEnemyShowType.Value != "Alive"))
					{
						continue;
					}
					TextMeshProUGUI val = enemyNames;
					((TMP_Text)val).text = ((TMP_Text)val).text + "<color=#" + difficultyColors[item.difficulty] + ">" + Truncate(item.enemyName, TimerPlugin_Config.configEnemyNameLimit.Value) + "</color>\n";
					if (TimerPlugin_Config.configEnemyShowType.Value == "DeadTimer" || TimerPlugin_Config.configEnemyShowType.Value == "ALL")
					{
						if (despawnedTimer > 0f)
						{
							TextMeshProUGUI obj2 = respawnTimes;
							((TMP_Text)obj2).text = ((TMP_Text)obj2).text + $"<b>{(int)despawnedTimer}s</b>\n";
						}
						else
						{
							TextMeshProUGUI obj3 = respawnTimes;
							((TMP_Text)obj3).text = ((TMP_Text)obj3).text + "<color=#ff3700><b>Dead</b></color>\n";
						}
					}
				}
			}
			if (((TMP_Text)enemyNames).text != "")
			{
				((Behaviour)header).enabled = true;
				scanlineObject.SetActive(true);
			}
		}

		public void BigMessage(string enemyName, Difficulty difficulty)
		{
			//IL_0019: 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)
			enemyToShow = Truncate(enemyName, TimerPlugin_Config.configEnemyNameLimit.Value);
			difficultyToShow = difficulty;
			showBigMessage = 3f;
		}

		protected override void Update()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			((SemiUI)this).Update();
			if (!TimerPlugin_Config.configEnemyTimerEnabled.Value)
			{
				((SemiUI)this).Hide();
				return;
			}
			if (showBigMessage > 0f)
			{
				showBigMessage -= Time.deltaTime;
				SemiFunc.UIBigMessage("<color=#" + difficultyColors[difficultyToShow] + ">" + enemyToShow + "</color> respawned", "{!}", 20f, Color.white, Color.white);
			}
			((SemiUI)this).Hide();
		}
	}
	public class IdleCountdownUI : SemiUI
	{
		public static IdleCountdownUI instance;

		private TextMeshProUGUI Text;

		private bool setup = true;

		private float lastDanceTime = 5f;

		public static FieldInfo spawnIdleTimerField;

		public EnemyParent enemyToCheck;

		public Vector3 lastPosition;

		protected override void Start()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_009a: 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)
			((SemiUI)this).Start();
			instance = this;
			spawnIdleTimerField = AccessTools.Field(typeof(EnemyDirector), "spawnIdlePauseTimer");
			Text = ((Component)this).GetComponent<TextMeshProUGUI>();
			((TMP_Text)Text).text = "00:00";
			((Graphic)Text).color = new Color(1f, 0.4f, 0.2f, 1f);
			((TMP_Text)Text).fontSize = 18f;
			base.showPosition = new Vector2(-330f, 100f);
			base.hidePosition = new Vector2(-430f, 100f);
		}

		protected override void Update()
		{
			//IL_0079: 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)
			((SemiUI)this).Update();
			if (lastDanceTime <= 0f || !TimerPlugin_Config.configIdleCountdownEnabled.Value)
			{
				((SemiUI)this).Hide();
			}
			else if (setup && LevelGenerator.Instance.Generated)
			{
				setup = false;
				enemyToCheck = EnemyDirector.instance.enemiesSpawned[0];
				lastPosition = ((Component)enemyToCheck).transform.position;
			}
			else if (!setup && SemiFunc.EnemySpawnIdlePause())
			{
				if (!SemiFunc.IsMasterClientOrSingleplayer())
				{
					HandleHostIdleStatus();
				}
				else
				{
					HandleClientIdleStatus();
				}
			}
			else if (lastDanceTime > 0f)
			{
				((TMP_Text)Text).text = "No Idle";
				lastDanceTime -= Time.deltaTime;
			}
		}

		private void HandleHostIdleStatus()
		{
			float num = (float)spawnIdleTimerField.GetValue(EnemyDirector.instance);
			if (num <= 0f)
			{
				((TMP_Text)Text).text = "No Idle";
				return;
			}
			int num2 = Mathf.FloorToInt(num / 60f);
			int num3 = Mathf.FloorToInt(num % 60f);
			((TMP_Text)Text).text = $"{num2:00}:{num3:00}";
		}

		private void HandleClientIdleStatus()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//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)
			bool flag = ((Component)enemyToCheck).transform.position == lastPosition;
			((TMP_Text)Text).text = (flag ? "Idle" : "No Idle");
			lastPosition = ((Component)enemyToCheck).transform.position;
		}
	}
	public class LevelTimerUI : SemiUI
	{
		public static LevelTimerUI instance;

		private TextMeshProUGUI Text;

		private bool setup = true;

		private float levelTimerElapsedTime;

		protected override void Start()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			((SemiUI)this).Start();
			instance = this;
			Text = ((Component)this).GetComponent<TextMeshProUGUI>();
			((TMP_Text)Text).text = "00:00";
			((Graphic)Text).color = new Color(0f, 0.75f, 1f, 1f);
			((TMP_Text)Text).fontSize = 18f;
			base.showPosition = new Vector2(-330f, 120f);
			base.hidePosition = new Vector2(-430f, 120f);
			levelTimerElapsedTime = 0f;
		}

		protected override void Update()
		{
			((SemiUI)this).Update();
			if (!TimerPlugin_Config.configLevelTimerEnabled.Value)
			{
				((SemiUI)this).Hide();
				return;
			}
			levelTimerElapsedTime += Time.deltaTime;
			if (setup)
			{
				if (LevelGenerator.Instance.Generated)
				{
					setup = false;
				}
			}
			else if (!((Object)(object)Text == (Object)null))
			{
				int num = Mathf.FloorToInt(levelTimerElapsedTime / 60f);
				int num2 = Mathf.FloorToInt(levelTimerElapsedTime % 60f);
				((TMP_Text)Text).text = $"{num:00}:{num2:00}";
			}
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "GenerateDone")]
	public class LevelGenerator_GenerateDone_Patcher
	{
		private static GameObject CreateFromHealth<T>(string name) where T : SemiUI
		{
			GameObject val = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud");
			GameObject val2 = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud/Health");
			GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform);
			Object.DestroyImmediate((Object)(object)val3.GetComponent<HealthUI>());
			Transform[] array = ((IEnumerable)val3.transform).Cast<Transform>().ToArray();
			foreach (Transform val4 in array)
			{
				Object.DestroyImmediate((Object)(object)((Component)val4).gameObject, true);
			}
			((Object)val3).name = name;
			val3.AddComponent<T>();
			return val3;
		}

		private static void CreateEnemyList()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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)
			GameObject val = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud");
			GameObject val2 = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud/Stats");
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Plugin.Logger.LogError((object)$"CreateEnemyList: Required GameObjects not found (hudParent={val}, originalStats={val2})");
				return;
			}
			GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform);
			((Object)val3).name = "EnemyListUI";
			Transform val4 = val3.transform.Find("StatsNumbers");
			if ((Object)(object)val4 != (Object)null)
			{
				((Object)val4).name = "RespawnTimes";
				RectTransform component = ((Component)val4).GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2(80f, 0f);
				GameObject val5 = Object.Instantiate<GameObject>(((Component)val4).gameObject, val3.transform);
				((Object)val5).name = "EnemyNames";
				RectTransform component2 = val5.GetComponent<RectTransform>();
				component2.anchoredPosition = new Vector2(20f, 0f);
			}
			else
			{
				Plugin.Logger.LogWarning((object)"CreateEnemyList: Could not find StatsNumbers under cloned Stats prefab.");
			}
			Transform val6 = val3.transform.Find("Upgrades Header");
			if ((Object)(object)val6 != (Object)null)
			{
				((Object)val6).name = "EnemiesHeader";
				RectTransform component3 = ((Component)val6).GetComponent<RectTransform>();
				component3.anchoredPosition = Vector2.op_Implicit(new Vector3(-30f, 60f));
			}
			else
			{
				Plugin.Logger.LogWarning((object)"CreateEnemyList: Could not find Upgrades Header under cloned Stats prefab.");
			}
			EnemyListUI enemyListUI = val3.AddComponent<EnemyListUI>();
			StatsUI component4 = val3.GetComponent<StatsUI>();
			if ((Object)(object)component4 != (Object)null)
			{
				enemyListUI.scanlineObject = ((Component)component4).GetComponent<StatsUI>().scanlineObject;
				Object.DestroyImmediate((Object)(object)component4);
				Object.DestroyImmediate((Object)(object)val3.GetComponent<TextMeshProUGUI>());
			}
			else
			{
				Plugin.Logger.LogWarning((object)"CreateEnemyList: Could not find StatsUI");
			}
		}

		private static void Postfix()
		{
			try
			{
				if (SemiFunc.RunIsLevel())
				{
					CreateFromHealth<LevelTimerUI>("LevelTimer");
					CreateFromHealth<IdleCountdownUI>("IdleCountdown");
					CreateEnemyList();
				}
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Exception in LevelGenerator.GenerateDone patch:\n{arg}");
			}
		}
	}
	[HarmonyPatch(typeof(MapToolController), "Update")]
	public class MapToolController_Update_Patch
	{
		private static FieldRef<MapToolController, PhotonView> photonViewRef = AccessTools.FieldRefAccess<MapToolController, PhotonView>("photonView");

		private static FieldRef<MapToolController, bool> activeRef = AccessTools.FieldRefAccess<MapToolController, bool>("Active");

		private static void Postfix(MapToolController __instance)
		{
			if ((!GameManager.Multiplayer() || photonViewRef.Invoke(__instance).IsMine) && activeRef.Invoke(__instance) && (Object)(object)EnemyListUI.instance != (Object)null)
			{
				((SemiUI)EnemyListUI.instance).Show();
				EnemyListUI.instance.Fetch();
			}
		}
	}
	[HarmonyPatch(typeof(MenuPage), "LockAndHide")]
	public class MenuPage_LockAndHide_Patch
	{
		private static void Postfix()
		{
			LevelTimerUI instance = LevelTimerUI.instance;
			if (instance != null)
			{
				((SemiUI)instance).Hide();
			}
			IdleCountdownUI instance2 = IdleCountdownUI.instance;
			if (instance2 != null)
			{
				((SemiUI)instance2).Hide();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "SpawnRPC")]
	public class EnemyParent_SpawnRPC_Patch
	{
		private static void Postfix(EnemyParent __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (TimerPlugin_Config.configEnemyTimerEnabled.Value && Object.op_Implicit((Object)(object)EnemyListUI.instance))
			{
				EnemyListUI.instance.BigMessage(__instance.enemyName, __instance.difficulty);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "OnPhotonSerializeView")]
	public class EnemyParent_OnPhotonSerializeView_Patch
	{
		private static bool isHostModded;

		private static bool hasCheckedHost;

		private static void Postfix(PhotonStream stream, PhotonMessageInfo info, EnemyParent __instance)
		{
			if (stream.IsWriting)
			{
				stream.SendNext((object)__instance.DespawnedTimer);
			}
			else
			{
				if (!isHostModded && hasCheckedHost)
				{
					return;
				}
				try
				{
					__instance.DespawnedTimer = (float)stream.ReceiveNext();
					isHostModded = true;
				}
				catch (Exception ex) when (ex is IndexOutOfRangeException || ex is InvalidCastException)
				{
					if (!hasCheckedHost)
					{
						Plugin.Logger.LogWarning((object)"Host doesn't have Timer Mod or sent invalid data.");
					}
					isHostModded = false;
				}
				finally
				{
					hasCheckedHost = true;
				}
			}
		}
	}
	[BepInPlugin("TimerPlugin", "Timer Plugin", "1.2.0")]
	[BepInProcess("REPO.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource Logger;

		public TimerPlugin_Config ConfigInstance;

		private static Harmony _harmony = new Harmony("TimerPlugin");

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			ConfigInstance = new TimerPlugin_Config(((BaseUnityPlugin)this).Config);
			ConfigInstance.RegisterOptions();
			if (TimerPlugin_Config.configPluginEnabled.Value)
			{
				_harmony.PatchAll();
				Logger.LogInfo((object)"Plugin Loaded");
			}
			else
			{
				Logger.LogWarning((object)"Plugin disabled in config");
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TimerPlugin";

		public const string PLUGIN_NAME = "Timer Plugin";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}