using System;
using System.Collections;
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.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("Timer Plugin")]
[assembly: AssemblyTitle("TimerPlugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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 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
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>()));
}
}
public class EnemyListUI : SemiUI
{
private TextMeshProUGUI enemyNames;
private TextMeshProUGUI respawnTimes;
private TextMeshProUGUI header;
public GameObject scanlineObject;
private float showBigMessage;
private bool fetched;
public static EnemyListUI instance;
private FieldInfo showTimerField;
public float despawnedTimer;
private string colorTier1;
private string colorTier2;
private string colorTier3;
private string enemyToShow;
private Difficulty difficultyToShow;
protected override void Start()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
((SemiUI)this).Start();
colorTier1 = ColorUtility.ToHtmlStringRGB(new Color(0.3373f, 1f, 0.4275f, 1f));
colorTier2 = ColorUtility.ToHtmlStringRGB(new Color(1f, 0.5529f, 0f, 1f));
colorTier3 = ColorUtility.ToHtmlStringRGB(new Color(0.8f, 0f, 0f, 1f));
showTimerField = typeof(SemiUI).GetField("showTimer", BindingFlags.Instance | BindingFlags.NonPublic);
instance = this;
enemyNames = ((Component)this).GetComponent<TextMeshProUGUI>();
respawnTimes = ((Component)((Component)this).transform.Find("RespawnTimes")).GetComponent<TextMeshProUGUI>();
header = ((Component)((Component)this).transform.Find("Enemies Header")).GetComponent<TextMeshProUGUI>();
((TMP_Text)enemyNames).text = "";
((TMP_Text)respawnTimes).text = "";
((TMP_Text)header).text = "Enemies";
((TMP_Text)respawnTimes).alignment = (TextAlignmentOptions)2049;
((TMP_Text)respawnTimes).enableWordWrapping = false;
((TMP_Text)respawnTimes).overflowMode = (TextOverflowModes)0;
((Behaviour)header).enabled = false;
scanlineObject.SetActive(false);
base.showPosition = new Vector2(240f, 85f);
base.hidePosition = new Vector2(390f, 85f);
}
public string GetDifficultyColor(Difficulty difficulty)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: 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_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected I4, but got Unknown
return (int)difficulty switch
{
0 => colorTier1,
1 => colorTier2,
2 => colorTier3,
_ => "FFFFFF",
};
}
public void Fetch()
{
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: 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 num = item.DespawnedTimer;
bool flag = SemiFunc.IsNotMasterClient();
if (flag)
{
num = (item.EnableObject.activeSelf ? 0f : 1f);
}
if ((double)num <= 1E-06)
{
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=#" + GetDifficultyColor(item.difficulty) + ">" + item.enemyName + "</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=#" + GetDifficultyColor(item.difficulty) + ">" + item.enemyName + "</color>\n";
if (TimerPlugin_Config.configEnemyShowType.Value == "DeadTimer" || TimerPlugin_Config.configEnemyShowType.Value == "ALL")
{
if (flag)
{
TextMeshProUGUI obj2 = respawnTimes;
((TMP_Text)obj2).text = ((TMP_Text)obj2).text + "<b>Dead</b>\n";
}
else
{
TextMeshProUGUI obj3 = respawnTimes;
((TMP_Text)obj3).text = ((TMP_Text)obj3).text + $"<b>{num:F1}s</b>\n";
}
}
}
}
if (((TMP_Text)enemyNames).text != "")
{
((Behaviour)header).enabled = true;
scanlineObject.SetActive(true);
}
}
public void BigMessage(string enemyName, Difficulty difficulty)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
enemyToShow = enemyName;
difficultyToShow = difficulty;
showBigMessage = 2f;
}
protected override void Update()
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
if (!TimerPlugin_Config.configEnemyTimerEnabled.Value)
{
((SemiUI)this).Hide();
return;
}
((SemiUI)this).Update();
((SemiUI)this).Hide();
if (showBigMessage > 0f)
{
showBigMessage -= Time.deltaTime;
SemiFunc.UIBigMessage("<color=#" + GetDifficultyColor(difficultyToShow) + ">" + enemyToShow + "</color> respawned", "{!}", 20f, Color.white, Color.white);
}
if ((float)showTimerField.GetValue(this) > 0f)
{
if (!fetched)
{
Fetch();
}
}
else
{
fetched = false;
}
}
}
public class IdleCountdownUI : SemiUI
{
public static IdleCountdownUI instance;
private TextMeshProUGUI Text;
private bool setup = true;
private bool isIdle = true;
public static FieldInfo spawnIdleTimerField;
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()
{
((SemiUI)this).Update();
if (!isIdle || !TimerPlugin_Config.configIdleCountdownEnabled.Value)
{
((SemiUI)this).Hide();
}
else if (setup)
{
if (LevelGenerator.Instance.Generated)
{
setup = false;
}
}
else if (!((Object)(object)Text == (Object)null))
{
float num = (float)spawnIdleTimerField.GetValue(EnemyDirector.instance);
if (num <= 0f)
{
((TMP_Text)Text).text = "No Idle";
isIdle = false;
}
else
{
int num2 = Mathf.FloorToInt(num / 60f);
int num3 = Mathf.FloorToInt(num % 60f);
((TMP_Text)Text).text = $"{num2:00}:{num3:00}";
}
}
}
}
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 void CreateFromHealth<T>(string objectName) 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.Destroy((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 = objectName;
val3.AddComponent<T>();
}
private static void CreateTimers()
{
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);
GameObject val4 = Object.Instantiate<GameObject>(val2, val.transform);
Object.Destroy((Object)(object)val3.GetComponent<HealthUI>());
Object.Destroy((Object)(object)val4.GetComponent<HealthUI>());
Transform[] array = ((IEnumerable)val3.transform).Cast<Transform>().ToArray();
foreach (Transform val5 in array)
{
Object.DestroyImmediate((Object)(object)((Component)val5).gameObject, true);
}
Transform[] array2 = ((IEnumerable)val4.transform).Cast<Transform>().ToArray();
foreach (Transform val6 in array2)
{
Object.DestroyImmediate((Object)(object)((Component)val6).gameObject, true);
}
((Object)val3).name = "LevelTimer";
val3.AddComponent<LevelTimerUI>();
((Object)val4).name = "IdleCountdown";
val4.AddComponent<IdleCountdownUI>();
}
private static void CreateEnemyList()
{
//IL_006f: 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_00b3: 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");
GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform);
((Object)val3).name = "EnemyList";
Transform val4 = val3.transform.Find("StatsNumbers");
Transform val5 = val3.transform.Find("Upgrades Header");
((Object)val4).name = "RespawnTimes";
val4.localPosition = new Vector3(100f, -25f, 0f);
((Component)val4).GetComponent<RectTransform>().sizeDelta = new Vector2(100f, 62f);
((Object)val5).name = "Enemies Header";
val5.localPosition = new Vector3(-30f, 60f, 0f);
EnemyListUI enemyListUI = val3.AddComponent<EnemyListUI>();
StatsUI component = val3.GetComponent<StatsUI>();
enemyListUI.scanlineObject = ((Component)component).GetComponent<StatsUI>()?.scanlineObject;
if ((Object)(object)component != (Object)null)
{
Object.DestroyImmediate((Object)(object)component);
}
}
private static void Postfix()
{
try
{
if (Enumerable.Contains(RunManager.instance.levels, RunManager.instance.levelCurrent))
{
if (TimerPlugin_Config.configLevelTimerEnabled.Value)
{
CreateFromHealth<LevelTimerUI>("LevelTimer");
}
if (TimerPlugin_Config.configIdleCountdownEnabled.Value)
{
CreateFromHealth<IdleCountdownUI>("IdleCountdown");
}
if (TimerPlugin_Config.configEnemyTimerEnabled.Value)
{
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();
}
}
}
[HarmonyPatch(typeof(MenuPage), "LockAndHide")]
public class MenuPage_LockAndHide_Patch
{
private static void Postfix()
{
if ((Object)(object)LevelTimerUI.instance != (Object)null && (Object)(object)IdleCountdownUI.instance != (Object)null)
{
((SemiUI)LevelTimerUI.instance).Hide();
((SemiUI)IdleCountdownUI.instance).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);
}
}
}
[BepInPlugin("TimerPlugin", "Timer Plugin", "1.1.1")]
[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.1.1";
}
}