using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using SineusModding.Api; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("LiveStatsOverlay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+63ffd79485e61d9beff65c00373ad93470153263")] [assembly: AssemblyProduct("LiveStatsOverlay")] [assembly: AssemblyTitle("LiveStatsOverlay")] [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; } } } namespace LiveStatsOverlay { internal class OverlaySettings { public readonly ConfigEntry ToggleOverlayKey; public readonly ConfigEntry ToggleSettingsKey; public readonly ConfigEntry OverlayVisible; public readonly ConfigEntry FontSize; public readonly ConfigEntry UpdateInterval; public readonly ConfigEntry PanelX; public readonly ConfigEntry PanelY; public readonly ConfigEntry DockToObjectiveBanner; public readonly ConfigEntry DockToDpsMeter; public readonly ConfigEntry Template; public readonly ConfigEntry ColorizeStatValues; public readonly ConfigEntry ShowWeaponsSection; public readonly ConfigEntry ShowWeaponStatsSection; public readonly ConfigEntry ShowPassivesSection; public readonly ConfigEntry ShowItemsSection; public readonly ConfigEntry ShowChoiceCounters; private readonly ConfigEntry templateVersion; private const int CurrentTemplateVersion = 5; public const string DefaultTemplate = "Time: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]"; private static readonly HashSet KnownPriorDefaults = new HashSet { "Live Stats\nHealth: [Health]\nRegeneration: [HealthRegeneration]\nBarrier: [Barrier]\nCooldown: [Cooldown]\nDamage: [DamageModifier]\nCrit Chance: [CritChance]\nCrit Damage: [CritDamage]\nDuration: [Duration]\nElites Damage: [ElitesDamage]\nSpeed: [MovementSpeed]\nEvasion: [Evasion]\nExperience Bonus: [ExperienceBonus]\nLifesteal Chance: [LifestealChance]\nProjectiles Count: [ProjectileCount]\nArmor: [Armor]\nSize: [Size]\nMagnet: [Magnet]\nJumps: [JumpsCount]\nJump Height: [JumpHeight]\nTower Respawn Time: [TowerCooldown]\nAltar Charge Speed: [AltarChargeSpeed]\nLuck: [Luck]\nBonus Chest Frequency: [ChestChance]\n\nCombat\nKills: [kills]\nTotal Damage: [totalDamage]\n\nWeapons\n[weapons]\nPassives\n[passives]\nItems\n[items]", "Live Stats\nObjective: [questStep]\nHealth: [Health]\nRegeneration: [HealthRegeneration]\nBarrier: [Barrier]\nCooldown: [Cooldown]\nDamage: [DamageModifier]\nCrit Chance: [CritChance]\nCrit Damage: [CritDamage]\nDuration: [Duration]\nElites Damage: [ElitesDamage]\nSpeed: [MovementSpeed]\nEvasion: [Evasion]\nExperience Bonus: [ExperienceBonus]\nLifesteal Chance: [LifestealChance]\nProjectiles Count: [ProjectileCount]\nArmor: [Armor]\nSize: [Size]\nMagnet: [Magnet]\nJumps: [JumpsCount]\nJump Height: [JumpHeight]\nTower Respawn Time: [TowerCooldown]\nAltar Charge Speed: [AltarChargeSpeed]\nLuck: [Luck]\nBonus Chest Frequency: [ChestChance]\n\nCombat\nKills: [kills]\nTotal Damage: [totalDamage]\n\nWeapons\n[weapons]\nPassives\n[passives]\nItems\n[items]", "Live Stats\nDPS (10s avg): [dps]\nObjective: [questStep]\nHealth: [Health]\nRegeneration: [HealthRegeneration]\nBarrier: [Barrier]\nCooldown: [Cooldown]\nDamage: [DamageModifier]\nCrit Chance: [CritChance]\nCrit Damage: [CritDamage]\nDuration: [Duration]\nElites Damage: [ElitesDamage]\nSpeed: [MovementSpeed]\nEvasion: [Evasion]\nExperience Bonus: [ExperienceBonus]\nLifesteal Chance: [LifestealChance]\nProjectiles Count: [ProjectileCount]\nArmor: [Armor]\nSize: [Size]\nMagnet: [Magnet]\nJumps: [JumpsCount]\nJump Height: [JumpHeight]\nTower Respawn Time: [TowerCooldown]\nAltar Charge Speed: [AltarChargeSpeed]\nLuck: [Luck]\nBonus Chest Frequency: [ChestChance]\n\nCombat\nKills: [kills]\nTotal Damage: [totalDamage]\n\nWeapons\n[weapons]\nPassives\n[passives]\nItems\n[items]", "Live Stats [questStep]\nTime: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]\n\nWeapons [weapons]\nPassives [passives]\nItems [items]", "[questStep]\nTime: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]\n\nWeapons [weapons]\nPassives [passives]\nItems [items]", "Time: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]\n\nWeapons [weapons]\nPassives [passives]\nItems [items]" }; public OverlaySettings(ConfigFile config) { ToggleOverlayKey = config.Bind("General", "ToggleOverlayKey", (KeyCode)290, "Key to show/hide the stats overlay."); ToggleSettingsKey = config.Bind("General", "ToggleSettingsKey", (KeyCode)291, "Key to open/close the overlay settings window."); OverlayVisible = config.Bind("General", "OverlayVisible", true, "Whether the overlay is visible by default."); FontSize = config.Bind("General", "FontSize", 13, "Font size for the overlay text."); UpdateInterval = config.Bind("General", "UpdateInterval", 0.25f, "Seconds between stat text refreshes. Lower is more responsive but costs more performance."); PanelX = config.Bind("Position", "PanelX", 12f, "X position (pixels from left) of the overlay panel. Only used when DockToObjectiveBanner is false. Drag the panel's title bar in-game to change, or edit here."); PanelY = config.Bind("Position", "PanelY", 12f, "Y position (pixels from top) of the overlay panel. Only used when DockToObjectiveBanner is false."); DockToObjectiveBanner = config.Bind("Position", "DockToObjectiveBanner", true, "If true, the panel automatically positions itself directly underneath the game's own \"Find the boss's lair\" style objective banner, instead of a fixed/draggable position. If the banner can't be found (e.g. very early in a match), falls back to PanelX/PanelY."); DockToDpsMeter = config.Bind("Position", "DockToDpsMeter", true, "If true and the separate DpsMeter mod is installed and visible, the panel docks directly above the DpsMeter window instead of the objective banner or a fixed position. Has no effect if DpsMeter isn't installed."); Template = config.Bind("Display", "Template", "Time: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]", "The text template shown in the overlay. Use [tokenName] placeholders (e.g. [Health], [MovementSpeed], [kills], [weapons]) which are replaced live with the local player's current stats. Supports Unity rich text (, , etc). Edit here or via the in-game settings window (F10 by default)."); ShowWeaponsSection = config.Bind("Sections", "ShowWeapons", true, "Show the Weapons line at the bottom of the overlay."); ShowPassivesSection = config.Bind("Sections", "ShowPassives", true, "Show the Passives line at the bottom of the overlay."); ShowItemsSection = config.Bind("Sections", "ShowItems", true, "Show the Items line at the bottom of the overlay."); ShowWeaponStatsSection = config.Bind("Sections", "ShowWeaponStats", true, "Show a per-weapon DPS (10s rolling) and kill count breakdown at the bottom of the overlay. Kills are attributed heuristically to whichever weapon most recently dealt damage - the game itself doesn't track kills per weapon."); ShowChoiceCounters = config.Bind("Display", "ShowChoiceCounters", true, "On the \"Make a choice\" buff-selection screen, show how many Rerolls/Skips/Bans you have left above the choices."); ColorizeStatValues = config.Bind("Display", "ColorizeStatValues", true, "Colorize stat values by category, LookingGlass-style: damage stats red, healing/HP green (turning yellow/red as HP drops), utility stats teal, kills gold. Turn off for plain white values."); templateVersion = config.Bind("Display", "TemplateVersion", 0, "Internal - tracks which built-in template you last had, so mod updates that redesign the default template can offer to replace an old auto-generated one without touching a template you've hand-edited. Don't edit this directly."); ForceUpgradeTemplateIfOutdated(); } private void ForceUpgradeTemplateIfOutdated() { if (templateVersion.Value < 5) { if (Template.Value == "Time: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]" || KnownPriorDefaults.Contains(Template.Value)) { Template.Value = "Time: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]"; } templateVersion.Value = 5; } } } internal class OverlayWindows { private delegate bool TryGetRect(out Rect rect); private const int StatsWindowId = 659918; private const int SettingsWindowId = 659919; private readonly OverlaySettings settings; private bool settingsVisible; private Rect statsRect; private Rect settingsRect = new Rect(320f, 12f, 420f, 420f); private Vector2 settingsScroll; private Vector2 templateEditScroll; private string renderedText = string.Empty; private float nextRenderTime; private string templateEditBuffer; private GUIStyle windowStyle; private GUIStyle choiceInlineTextStyle; private GUIStyle statsTextStyle; private GUIStyle labelStyle; private GUIStyle headerStyle; private GUIStyle textAreaStyle; private bool stylesReady; private Texture2D panelTexture; private Font uiFont; private static readonly ManualLogSource Log = Logger.CreateLogSource("LiveStatsOverlay.UI"); private bool objectiveSubscribed; private bool isDockedThisFrame; public OverlayWindows(OverlaySettings settings) { //IL_0015: 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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) this.settings = settings; statsRect = new Rect(settings.PanelX.Value, settings.PanelY.Value, 280f, 10f); templateEditBuffer = settings.Template.Value; } public void ToggleSettingsWindow() { settingsVisible = !settingsVisible; } public void Update() { LocalPlayerProgress.EnsureSubscribed(); EnsureObjectiveSubscribed(); CombatMeter.Tick(); WeaponCombatMeter.Tick(); StatTokens.ColorizeValues = settings.ColorizeStatValues.Value; if (Time.unscaledTime >= nextRenderTime) { renderedText = StatTemplate.Render(settings.Template.Value) + BuildToggledSections(); nextRenderTime = Time.unscaledTime + Mathf.Max(0.05f, settings.UpdateInterval.Value); } } private string BuildToggledSections() { StringBuilder stringBuilder = new StringBuilder(); if (settings.ShowWeaponsSection.Value) { stringBuilder.Append("\nWeapons [weapons]"); } if (settings.ShowWeaponStatsSection.Value) { stringBuilder.Append("\nDPS / Kills per Weapon\n[weaponStats]"); } if (settings.ShowPassivesSection.Value) { stringBuilder.Append("\nPassives [passives]"); } if (settings.ShowItemsSection.Value) { stringBuilder.Append("\nItems [items]"); } if (stringBuilder.Length == 0) { return string.Empty; } stringBuilder.Insert(0, '\n'); return StatTemplate.Render(stringBuilder.ToString()); } private void EnsureObjectiveSubscribed() { if (!objectiveSubscribed) { MatchObjective.EnsureSubscribed(); MatchObjective.StepChanged += delegate { nextRenderTime = 0f; }; MatchObjective.BossLairFound += delegate { nextRenderTime = 0f; }; objectiveSubscribed = true; } } public void Draw() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: 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) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) EnsureStyles(); if (settings.OverlayVisible.Value && MatchObjective.IsInMatch) { Rect val = default(Rect); bool flag = settings.DockToDpsMeter.Value && DpsMeterHook.TryGetWindowScreenRect(ref val); Rect val2 = default(Rect); isDockedThisFrame = !flag && settings.DockToObjectiveBanner.Value && MatchObjective.TryGetObjectiveBannerScreenRect(ref val2); if (flag) { float num = Mathf.Max(240f, ((Rect)(ref val)).width); statsRect = new Rect(((Rect)(ref val)).xMax - num, ((Rect)(ref val)).yMin - ((Rect)(ref statsRect)).height - 6f, num, ((Rect)(ref statsRect)).height); statsRect = ClampToScreen(statsRect); statsRect = GUILayout.Window(659918, statsRect, new WindowFunction(DrawStatsWindow), "Live Stats", windowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num) }); } else if (isDockedThisFrame) { float num2 = Mathf.Max(240f, ((Rect)(ref val2)).width); statsRect = new Rect(((Rect)(ref val2)).xMax - num2, ((Rect)(ref val2)).yMax + 6f, num2, ((Rect)(ref statsRect)).height); statsRect = ClampToScreen(statsRect); statsRect = GUILayout.Window(659918, statsRect, new WindowFunction(DrawStatsWindow), "Live Stats", windowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num2) }); } else { statsRect = ClampToScreen(statsRect); statsRect = GUILayout.Window(659918, statsRect, new WindowFunction(DrawStatsWindow), "Live Stats", windowStyle, Array.Empty()); PersistPanelPosition(); } } int rerolls = default(int); int skips = default(int); int bans = default(int); if (settings.ShowChoiceCounters.Value && ChoicePanel.TryGetCounts(ref rerolls, ref skips, ref bans)) { DrawChoiceCounters(rerolls, skips, bans); } if (settingsVisible) { settingsRect = ClampToScreen(settingsRect); settingsRect = GUILayout.Window(659919, settingsRect, new WindowFunction(DrawSettingsWindow), "Live Stats Overlay - Settings", windowStyle, Array.Empty()); } } private void DrawChoiceCounters(int rerolls, int skips, int bans) { DrawChoiceBadge((TryGetRect)ChoicePanel.TryGetRerollButtonScreenRect, rerolls); DrawChoiceBadge((TryGetRect)ChoicePanel.TryGetSkipButtonScreenRect, skips); DrawChoiceBadge((TryGetRect)ChoicePanel.TryGetBanButtonScreenRect, bans); } private void DrawChoiceBadge(TryGetRect tryGetButtonRect, int count) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (tryGetButtonRect(out var rect)) { Rect val = ClampToScreen(new Rect(((Rect)(ref rect)).xMin + ((Rect)(ref rect)).width * 0.24f, ((Rect)(ref rect)).y + (((Rect)(ref rect)).height - 24f) / 2f, 40f, 24f)); string arg = ((count > 0) ? "#E6C478" : "#FF6B57"); string text = $"{count}"; GUI.Label(val, text, choiceInlineTextStyle); } } private static Rect ClampToScreen(Rect rect) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(((Rect)(ref rect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref rect)).width)); float num2 = Mathf.Clamp(((Rect)(ref rect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref rect)).height)); return new Rect(num, num2, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height); } private void PersistPanelPosition() { if (!Mathf.Approximately(((Rect)(ref statsRect)).x, settings.PanelX.Value)) { settings.PanelX.Value = ((Rect)(ref statsRect)).x; } if (!Mathf.Approximately(((Rect)(ref statsRect)).y, settings.PanelY.Value)) { settings.PanelY.Value = ((Rect)(ref statsRect)).y; } } private void DrawStatsWindow(int windowId) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(renderedText, statsTextStyle, Array.Empty()); if (!isDockedThisFrame) { GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f)); } } private void DrawSettingsWindow(int windowId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) settingsScroll = GUILayout.BeginScrollView(settingsScroll, Array.Empty()); settings.OverlayVisible.Value = GUILayout.Toggle(settings.OverlayVisible.Value, "Overlay Visible", Array.Empty()); settings.DockToObjectiveBanner.Value = GUILayout.Toggle(settings.DockToObjectiveBanner.Value, "Dock underneath the \"Find the boss's lair\" objective banner", Array.Empty()); if (DpsMeterHook.IsPresent) { settings.DockToDpsMeter.Value = GUILayout.Toggle(settings.DockToDpsMeter.Value, "Dock above the DpsMeter window (takes priority over the objective banner)", Array.Empty()); } settings.ColorizeStatValues.Value = GUILayout.Toggle(settings.ColorizeStatValues.Value, "Colorize values (damage red, HP green, utility teal, kills gold)", Array.Empty()); settings.ShowChoiceCounters.Value = GUILayout.Toggle(settings.ShowChoiceCounters.Value, "Show Rerolls/Skips/Bans left on the \"Make a choice\" screen", Array.Empty()); GUILayout.Space(6f); GUILayout.Label("Sections", headerStyle, Array.Empty()); settings.ShowWeaponsSection.Value = GUILayout.Toggle(settings.ShowWeaponsSection.Value, "Weapons", Array.Empty()); settings.ShowWeaponStatsSection.Value = GUILayout.Toggle(settings.ShowWeaponStatsSection.Value, "DPS / Kills per Weapon", Array.Empty()); settings.ShowPassivesSection.Value = GUILayout.Toggle(settings.ShowPassivesSection.Value, "Passives", Array.Empty()); settings.ShowItemsSection.Value = GUILayout.Toggle(settings.ShowItemsSection.Value, "Items", Array.Empty()); GUILayout.Space(6f); GUILayout.Label("Template", headerStyle, Array.Empty()); GUILayout.Label("Use [tokenName] placeholders, e.g. [Health] [MovementSpeed] [JumpsCount] [kills] [weapons]. Supports rich text (, ).", labelStyle, Array.Empty()); templateEditScroll = GUILayout.BeginScrollView(templateEditScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(180f) }); templateEditBuffer = GUILayout.TextArea(templateEditBuffer, textAreaStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.EndScrollView(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Apply", Array.Empty())) { settings.Template.Value = templateEditBuffer; nextRenderTime = 0f; } if (GUILayout.Button("Reset to Default", Array.Empty())) { templateEditBuffer = "Time: [matchTime] HP: [currentHealth]/[maxHealthCurrent] ([healthFraction])\n\nDPS (10s): [dps] Kills/min: [kpm]\nCombo Dmg: [comboDamage]\nKills: [kills] Total Damage: [totalDamage]\n\nDamage: [DamageModifier] Speed: [MovementSpeed] Cooldown: [Cooldown] Crit: [CritChance]"; settings.Template.Value = templateEditBuffer; nextRenderTime = 0f; } GUILayout.EndHorizontal(); GUILayout.Space(10f); GUILayout.Label("Display", headerStyle, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Font size", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); settings.FontSize.Value = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)settings.FontSize.Value, 8f, 24f, Array.Empty())); GUILayout.Label(settings.FontSize.Value.ToString(), labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Refresh (s)", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); settings.UpdateInterval.Value = GUILayout.HorizontalSlider(settings.UpdateInterval.Value, 0.05f, 2f, Array.Empty()); GUILayout.Label(settings.UpdateInterval.Value.ToString("0.00"), labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) }); GUILayout.EndHorizontal(); GUILayout.Space(10f); GUILayout.Label($"Toggle overlay: {settings.ToggleOverlayKey.Value}", labelStyle, Array.Empty()); GUILayout.Label($"Toggle this window: {settings.ToggleSettingsKey.Value}", labelStyle, Array.Empty()); GUILayout.Label((settings.DockToDpsMeter.Value && DpsMeterHook.IsPresent) ? "Docked above the DpsMeter window. Disable docking above to drag it freely." : (settings.DockToObjectiveBanner.Value ? "Docked underneath the objective banner. Disable docking above to drag it freely." : "Drag the Live Stats panel's title bar to reposition it."), labelStyle, Array.Empty()); GUILayout.EndScrollView(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f)); } private void EnsureStyles() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: 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_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_021c: 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_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Expected O, but got Unknown //IL_0240: Expected O, but got Unknown //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Expected O, but got Unknown //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: 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_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Expected O, but got Unknown //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Expected O, but got Unknown //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Expected O, but got Unknown if (!stylesReady || !((Object)(object)panelTexture != (Object)null) || !((Object)(object)uiFont != (Object)null)) { uiFont = UiFont.CreateSafe(new string[3] { "Segoe UI", "Segoe UI Semibold", "Arial" }, settings.FontSize.Value); Color fill = Color32.op_Implicit(new Color32((byte)10, (byte)26, (byte)34, (byte)235)); Color border = Color32.op_Implicit(new Color32((byte)198, (byte)158, (byte)74, byte.MaxValue)); Color textColor = Color32.op_Implicit(new Color32((byte)224, (byte)230, (byte)232, byte.MaxValue)); Color textColor2 = Color32.op_Implicit(new Color32((byte)230, (byte)196, (byte)120, byte.MaxValue)); panelTexture = MakeBorderedTexture(fill, border); GUIStyle val = new GUIStyle(GUI.skin.window) { font = uiFont, fontSize = settings.FontSize.Value + 1, fontStyle = (FontStyle)1, border = new RectOffset(2, 2, 2, 2), overflow = new RectOffset(0, 0, 0, 0), margin = new RectOffset(0, 0, 0, 0) }; val.normal.background = panelTexture; val.normal.textColor = textColor2; val.onNormal.background = panelTexture; val.onNormal.textColor = textColor2; val.hover.background = panelTexture; val.hover.textColor = textColor2; val.onHover.background = panelTexture; val.onHover.textColor = textColor2; val.active.background = panelTexture; val.active.textColor = textColor2; val.onActive.background = panelTexture; val.onActive.textColor = textColor2; val.focused.background = panelTexture; val.focused.textColor = textColor2; val.onFocused.background = panelTexture; val.onFocused.textColor = textColor2; val.padding = new RectOffset(10, 10, 22, 10); windowStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { font = uiFont, fontSize = settings.FontSize.Value }; val2.normal.textColor = textColor; labelStyle = val2; GUIStyle val3 = new GUIStyle(labelStyle) { fontStyle = (FontStyle)1 }; val3.normal.textColor = textColor2; headerStyle = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { font = uiFont, fontSize = settings.FontSize.Value, richText = true }; val4.normal.textColor = textColor; val4.wordWrap = true; statsTextStyle = val4; GUIStyle val5 = new GUIStyle(GUI.skin.textArea) { font = uiFont, fontSize = settings.FontSize.Value, wordWrap = true }; val5.normal.textColor = Color.black; textAreaStyle = val5; choiceInlineTextStyle = new GUIStyle(GUI.skin.label) { font = uiFont, fontSize = Mathf.Max(9, settings.FontSize.Value + 2), richText = true, alignment = (TextAnchor)3, wordWrap = false }; bool flag = stylesReady; stylesReady = true; Log.LogInfo((object)((flag ? "Rebuilt" : "Built") + " overlay styles (font: " + (((Object)(object)uiFont != (Object)null) ? ((Object)uiFont).name : "NULL") + ", panel texture: " + (((Object)(object)panelTexture != (Object)null) ? "ok" : "NULL") + ")")); } } private static Texture2D MakeBorderedTexture(Color fill, Color border) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_001b: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(12, 12, (TextureFormat)4, false) { filterMode = (FilterMode)0, hideFlags = (HideFlags)61 }; for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { bool flag = j < 2 || i < 2 || j >= 10 || i >= 10; val.SetPixel(j, i, flag ? border : fill); } } val.Apply(); return val; } } [BepInPlugin("com.community.sineusarena.livestatsoverlay", "Live Stats Overlay", "3.2.1")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.community.sineusarena.livestatsoverlay"; public const string PluginName = "Live Stats Overlay"; public const string PluginVersion = "3.2.1"; private const string GithubOwner = "maanu113"; private const string GithubRepo = "LiveStatsOverlay"; internal static OverlaySettings Settings; private OverlayWindows windows; private UpdateNotice updateNotice; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Settings = new OverlaySettings(((BaseUnityPlugin)this).Config); windows = new OverlayWindows(Settings); updateNotice = new UpdateNotice("Live Stats Overlay"); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded. Press {2} to show/hide, {3} for settings.", "Live Stats Overlay", "3.2.1", Settings.ToggleOverlayKey.Value, Settings.ToggleSettingsKey.Value)); UpdateChecker.CheckAsync((MonoBehaviour)(object)this, "maanu113", "LiveStatsOverlay", "3.2.1", (Action)delegate(UpdateCheckResult result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((int)result.Status == 3) { updateNotice.Show(result.LatestVersion, result.ReleaseUrl); } }); } private void Update() { //IL_000a: 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) if (Input.GetKeyDown(Settings.ToggleOverlayKey.Value)) { Settings.OverlayVisible.Value = !Settings.OverlayVisible.Value; } if (Input.GetKeyDown(Settings.ToggleSettingsKey.Value)) { windows.ToggleSettingsWindow(); } windows.Update(); } private void OnGUI() { windows.Draw(); updateNotice.Draw(); } } }