using System; using System.Diagnostics; using System.IO; 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 Pigeon.Movement; using Sparroh.UI; using TMPro; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AmalgamationTracker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AmalgamationTracker")] [assembly: AssemblyTitle("AmalgamationTracker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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; } } } public static class HudRepositionClient { private const string ApiTypeName = "HudRepositionAPI"; private static Type _apiType; private static MethodInfo _register; private static MethodInfo _unregister; private static bool _available; public static bool IsAvailable { get { EnsureResolved(); return _available; } } public static void Register(string id, string displayName, RectTransform rect, ConfigEntry anchorX, ConfigEntry anchorY) { if (!_available) { EnsureResolved(force: true); } if (!_available || (Object)(object)rect == (Object)null || anchorX == null || anchorY == null) { return; } try { _register.Invoke(null, new object[5] { id, displayName, rect, anchorX, anchorY }); } catch (Exception ex) { Debug.LogWarning((object)("[HudRepositionClient] Register failed: " + (ex.InnerException?.Message ?? ex.Message))); } } public static void Unregister(string id) { if (!_available) { EnsureResolved(force: true); } if (!_available || string.IsNullOrEmpty(id)) { return; } try { _unregister.Invoke(null, new object[1] { id }); } catch (Exception) { } } private static void EnsureResolved(bool force = false) { if (_available && !force) { return; } _apiType = null; _register = null; _unregister = null; _available = false; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType("HudRepositionAPI", throwOnError: false); if (type != null) { _apiType = type; break; } } catch { } } if (_apiType == null) { return; } MethodInfo[] methods = _apiType.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (methodInfo.Name == "Register" && parameters.Length == 5 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string) && typeof(RectTransform).IsAssignableFrom(parameters[2].ParameterType)) { _register = methodInfo; } else if (methodInfo.Name == "Unregister" && parameters.Length == 1 && parameters[0].ParameterType == typeof(string)) { _unregister = methodInfo; } } _available = _register != null && _unregister != null; } } [BepInPlugin("sparroh.amalgamationtracker", "AmalgamationTracker", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [MycoMod(/*Could not decode attribute arguments.*/)] public class SparrohPlugin : BaseUnityPlugin { public const string PluginGUID = "sparroh.amalgamationtracker"; public const string PluginName = "AmalgamationTracker"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Logger; private Harmony harmony; private BossTimer bossTimer; private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; try { harmony = new Harmony("sparroh.amalgamationtracker"); } catch (Exception ex) { Logger.LogError((object)("Failed to create Harmony instance: " + ex.Message)); return; } ConfigFile configFile = ((BaseUnityPlugin)this).Config; try { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.amalgamationtracker.cfg"); fileSystemWatcher.Changed += delegate { configFile.Reload(); }; fileSystemWatcher.EnableRaisingEvents = true; } catch (Exception ex2) { Logger.LogWarning((object)("Failed to set up config watcher: " + ex2.Message)); } try { bossTimer = new BossTimer(configFile, harmony); } catch (Exception ex3) { Logger.LogError((object)("Failed to initialize BossTimer: " + ex3.Message)); } try { harmony.PatchAll(); } catch (Exception ex4) { Logger.LogError((object)("Failed to apply Harmony patches: " + ex4.Message)); } Logger.LogInfo((object)"AmalgamationTracker loaded successfully."); } private void Update() { try { if (bossTimer != null) { bossTimer.UpdateHudVisibility(); } } catch (Exception ex) { Logger.LogError((object)("Error in BossTimer.UpdateHudVisibility(): " + ex.Message)); } try { if (bossTimer != null) { bossTimer.Update(); } } catch (Exception ex2) { Logger.LogError((object)("Error in BossTimer.Update(): " + ex2.Message)); } } private void OnDestroy() { try { if (bossTimer != null) { bossTimer.OnDestroy(); } } catch (Exception ex) { Logger.LogError((object)("Error in BossTimer.OnDestroy(): " + ex.Message)); } try { if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception ex2) { Logger.LogError((object)("Error unpatching Harmony: " + ex2.Message)); } } } public class BossTimer { private BossTimerHUD bossTimerHUD; private readonly ConfigFile configFile; private readonly Harmony harmony; public BossTimer(ConfigFile configFile, Harmony harmony) { this.configFile = configFile; this.harmony = harmony; bossTimerHUD = new BossTimerHUD(configFile, harmony); } public void UpdateHudVisibility() { bossTimerHUD.UpdateHudVisibility(); } public void Update() { bossTimerHUD.Update(); } public void OnDestroy() { bossTimerHUD.OnDestroy(); } } public class BossTimerHUD { private ConfigEntry enableBossTimerHUD; private ConfigEntry bossTimerAnchorX; private ConfigEntry bossTimerAnchorY; private ConfigColor valueColor; private HudHandle hud; private readonly ConfigFile configFile; private readonly Harmony harmony; private bool isTiming; private float startTime; private float finalTime; private bool hasFinalTime; public static BossTimerHUD Instance { get; private set; } private bool IsHudAlive { get { if (hud != null && (Object)(object)hud.GameObject != (Object)null) { return hud.Primary != null; } return false; } } public bool IsActive { get { if (IsHudAlive) { return hud.IsActive; } return false; } } public Vector2 GetSize { get { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!IsHudAlive) { return Vector2.zero; } return hud.Size; } } public BossTimerHUD(ConfigFile configFile, Harmony harmony) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) this.configFile = configFile; this.harmony = harmony; Instance = this; try { enableBossTimerHUD = configFile.Bind("General", "EnableBossTimerHUD", true, "Enables the Amalgamation boss timer HUD display."); enableBossTimerHUD.SettingChanged += OnEnableBossTimerHUDChanged; bossTimerAnchorX = configFile.Bind("HUD Positioning", "BossTimerAnchorX", 0.8229749f, "X anchor position for Boss Timer (0-1)."); bossTimerAnchorY = configFile.Bind("HUD Positioning", "BossTimerAnchorY", 0.9050629f, "Y anchor position for Boss Timer (0-1)."); bossTimerAnchorX.SettingChanged += OnAnchorChanged; bossTimerAnchorY.SettingChanged += OnAnchorChanged; valueColor = ConfigColor.Bind(configFile, "Colors", "ValueColor", UIColors.Amber, "Rich-text value color for the boss timer (hex RRGGBB or #RRGGBB)."); } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Failed to initialize BossTimerHUD: " + ex.Message)); } } public void UpdateHudVisibility() { if (!IsHudAlive) { ClearDestroyedHud(); } else { hud.SetActive(enableBossTimerHUD.Value); } } private void OnEnableBossTimerHUDChanged(object sender, EventArgs e) { if (!enableBossTimerHUD.Value && hud != null) { DestroyHud(); } UpdateHudVisibility(); } private void OnAnchorChanged(object sender, EventArgs e) { if (IsHudAlive) { hud.SetAnchor(bossTimerAnchorX.Value, bossTimerAnchorY.Value); } } private void ClearDestroyedHud() { if (hud == null) { return; } try { if ((Object)(object)hud.Rect != (Object)null) { HudRepositionClient.Unregister("sparroh.amalgamationtracker"); } } catch { } hud = null; } private void CreateTimerHUD() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsHudAlive) { ClearDestroyedHud(); hud = HudBuilder.Create("BossTimerHUD").ParentToReticle(true).Anchor(bossTimerAnchorX.Value, bossTimerAnchorY.Value) .Pivot(new Vector2(0.5f, 0.5f)) .Size(350f, 28f, true) .AddText("TimerText", 20f, (TextAlignmentOptions)514) .Build(); if (IsHudAlive) { HudRepositionClient.Register("sparroh.amalgamationtracker", "Boss Timer", hud.Rect, bossTimerAnchorX, bossTimerAnchorY); UpdateHudVisibility(); } } } private void DestroyHud() { HudRepositionClient.Unregister("sparroh.amalgamationtracker"); if (hud != null) { if ((Object)(object)hud.GameObject != (Object)null) { hud.Destroy(); } hud = null; } } public void StartTimer() { isTiming = true; startTime = Time.realtimeSinceStartup; finalTime = 0f; hasFinalTime = false; SparrohPlugin.Logger.LogInfo((object)"Boss timer started"); } public void StopTimer() { if (isTiming) { finalTime = Time.realtimeSinceStartup - startTime; isTiming = false; hasFinalTime = true; SparrohPlugin.Logger.LogInfo((object)("Boss timer stopped: " + FormatTime(finalTime))); } } public void ResetTimer() { isTiming = false; startTime = 0f; finalTime = 0f; hasFinalTime = false; SparrohPlugin.Logger.LogInfo((object)"Boss timer reset"); } public void Update() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) try { if (enableBossTimerHUD == null || !enableBossTimerHUD.Value) { return; } if (hud != null && !IsHudAlive) { ClearDestroyedHud(); } if (!((Object)(object)Player.LocalPlayer == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null)) { if (!IsHudAlive) { CreateTimerHUD(); } else if (hasFinalTime) { hud.Primary.SetRich("Amalgamation", FormatTime(finalTime), valueColor.Value, (string)null); } else if (isTiming) { hud.Primary.SetRich("Amalgamation", FormatTime(Time.realtimeSinceStartup - startTime), valueColor.Value, (string)null); } else { hud.Primary.Text = "Amalgamation: Waiting..."; } } } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in BossTimerHUD.Update(): " + ex.Message)); } } private string FormatTime(float timeInSeconds) { int num = (int)(timeInSeconds / 60f); int num2 = (int)(timeInSeconds % 60f); int num3 = (int)(timeInSeconds % 1f * 1000f); return $"{num:D2}:{num2:D2}.{num3:D3}"; } public void OnDestroy() { try { DestroyHud(); } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in BossTimerHUD.OnDestroy(): " + ex.Message)); } } } [HarmonyPatch] public static class BossTimerPatches { [HarmonyPatch(typeof(MissionManager), "OnMissionStarted_Client")] [HarmonyPostfix] private static void OnMissionStarted_Client_Postfix() { if (BossTimerHUD.Instance != null) { BossTimerHUD.Instance.ResetTimer(); } } [HarmonyPatch(typeof(AmalgamationObjective), "OnAmalgamationSpawned_ClientRpc")] [HarmonyPostfix] private static void OnAmalgamationSpawned_ClientRpc_Postfix(AmalgamationObjective __instance, NetworkBehaviourReference brainRef) { if (BossTimerHUD.Instance != null) { BossTimerHUD.Instance.StartTimer(); } } [HarmonyPatch(typeof(AmalgamationObjective), "OnBrainKilled")] [HarmonyPostfix] private static void OnBrainKilled_Postfix(EnemyBrain brain) { if (BossTimerHUD.Instance != null) { BossTimerHUD.Instance.StopTimer(); } } } namespace AmalgamationTracker { public static class MyPluginInfo { public const string PLUGIN_GUID = "AmalgamationTracker"; public const string PLUGIN_NAME = "AmalgamationTracker"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }