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<KeyCode> ToggleOverlayKey;
public readonly ConfigEntry<KeyCode> ToggleSettingsKey;
public readonly ConfigEntry<bool> OverlayVisible;
public readonly ConfigEntry<int> FontSize;
public readonly ConfigEntry<float> UpdateInterval;
public readonly ConfigEntry<float> PanelX;
public readonly ConfigEntry<float> PanelY;
public readonly ConfigEntry<bool> DockToObjectiveBanner;
public readonly ConfigEntry<bool> DockToDpsMeter;
public readonly ConfigEntry<string> Template;
public readonly ConfigEntry<bool> ColorizeStatValues;
public readonly ConfigEntry<bool> ShowWeaponsSection;
public readonly ConfigEntry<bool> ShowWeaponStatsSection;
public readonly ConfigEntry<bool> ShowPassivesSection;
public readonly ConfigEntry<bool> ShowItemsSection;
public readonly ConfigEntry<bool> ShowChoiceCounters;
private readonly ConfigEntry<int> templateVersion;
private const int CurrentTemplateVersion = 5;
public const string DefaultTemplate = "<color=#9FB4BA>Time:</color> <color=#FFFFFF>[matchTime]</color> <color=#9FB4BA>HP:</color> <color=#FFFFFF>[currentHealth]/[maxHealthCurrent] ([healthFraction])</color>\n\n<color=#9FB4BA>DPS (10s):</color> <color=#FFFFFF>[dps]</color> <color=#9FB4BA>Kills/min:</color> <color=#FFFFFF>[kpm]</color>\n<color=#9FB4BA>Combo Dmg:</color> <color=#FFFFFF>[comboDamage]</color>\n<color=#9FB4BA>Kills:</color> <color=#FFFFFF>[kills]</color> <color=#9FB4BA>Total Damage:</color> <color=#FFFFFF>[totalDamage]</color>\n\n<color=#9FB4BA>Damage:</color> <color=#FFFFFF>[DamageModifier]</color> <color=#9FB4BA>Speed:</color> <color=#FFFFFF>[MovementSpeed]</color> <color=#9FB4BA>Cooldown:</color> <color=#FFFFFF>[Cooldown]</color> <color=#9FB4BA>Crit:</color> <color=#FFFFFF>[CritChance]</color>";
private static readonly HashSet<string> KnownPriorDefaults = new HashSet<string> { "<b>Live Stats</b>\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\n<b>Combat</b>\nKills: [kills]\nTotal Damage: [totalDamage]\n\n<b>Weapons</b>\n[weapons]\n<b>Passives</b>\n[passives]\n<b>Items</b>\n[items]", "<b>Live Stats</b>\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\n<b>Combat</b>\nKills: [kills]\nTotal Damage: [totalDamage]\n\n<b>Weapons</b>\n[weapons]\n<b>Passives</b>\n[passives]\n<b>Items</b>\n[items]", "<b>Live Stats</b>\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\n<b>Combat</b>\nKills: [kills]\nTotal Damage: [totalDamage]\n\n<b>Weapons</b>\n[weapons]\n<b>Passives</b>\n[passives]\n<b>Items</b>\n[items]", "<b>Live Stats</b> [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\n<b>Weapons</b> [weapons]\n<b>Passives</b> [passives]\n<b>Items</b> [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\n<b>Weapons</b> [weapons]\n<b>Passives</b> [passives]\n<b>Items</b> [items]", "<color=#9FB4BA>Time:</color> <color=#FFFFFF>[matchTime]</color> <color=#9FB4BA>HP:</color> <color=#FFFFFF>[currentHealth]/[maxHealthCurrent] ([healthFraction])</color>\n\n<color=#9FB4BA>DPS (10s):</color> <color=#FFFFFF>[dps]</color> <color=#9FB4BA>Kills/min:</color> <color=#FFFFFF>[kpm]</color>\n<color=#9FB4BA>Combo Dmg:</color> <color=#FFFFFF>[comboDamage]</color>\n<color=#9FB4BA>Kills:</color> <color=#FFFFFF>[kills]</color> <color=#9FB4BA>Total Damage:</color> <color=#FFFFFF>[totalDamage]</color>\n\n<color=#9FB4BA>Damage:</color> <color=#FFFFFF>[DamageModifier]</color> <color=#9FB4BA>Speed:</color> <color=#FFFFFF>[MovementSpeed]</color> <color=#9FB4BA>Cooldown:</color> <color=#FFFFFF>[Cooldown]</color> <color=#9FB4BA>Crit:</color> <color=#FFFFFF>[CritChance]</color>\n\n<color=#E6C478><b>Weapons</b></color> <color=#FFFFFF>[weapons]</color>\n<color=#E6C478><b>Passives</b></color> <color=#FFFFFF>[passives]</color>\n<color=#E6C478><b>Items</b></color> <color=#FFFFFF>[items]</color>" };
public OverlaySettings(ConfigFile config)
{
ToggleOverlayKey = config.Bind<KeyCode>("General", "ToggleOverlayKey", (KeyCode)290, "Key to show/hide the stats overlay.");
ToggleSettingsKey = config.Bind<KeyCode>("General", "ToggleSettingsKey", (KeyCode)291, "Key to open/close the overlay settings window.");
OverlayVisible = config.Bind<bool>("General", "OverlayVisible", true, "Whether the overlay is visible by default.");
FontSize = config.Bind<int>("General", "FontSize", 13, "Font size for the overlay text.");
UpdateInterval = config.Bind<float>("General", "UpdateInterval", 0.25f, "Seconds between stat text refreshes. Lower is more responsive but costs more performance.");
PanelX = config.Bind<float>("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<float>("Position", "PanelY", 12f, "Y position (pixels from top) of the overlay panel. Only used when DockToObjectiveBanner is false.");
DockToObjectiveBanner = config.Bind<bool>("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<bool>("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<string>("Display", "Template", "<color=#9FB4BA>Time:</color> <color=#FFFFFF>[matchTime]</color> <color=#9FB4BA>HP:</color> <color=#FFFFFF>[currentHealth]/[maxHealthCurrent] ([healthFraction])</color>\n\n<color=#9FB4BA>DPS (10s):</color> <color=#FFFFFF>[dps]</color> <color=#9FB4BA>Kills/min:</color> <color=#FFFFFF>[kpm]</color>\n<color=#9FB4BA>Combo Dmg:</color> <color=#FFFFFF>[comboDamage]</color>\n<color=#9FB4BA>Kills:</color> <color=#FFFFFF>[kills]</color> <color=#9FB4BA>Total Damage:</color> <color=#FFFFFF>[totalDamage]</color>\n\n<color=#9FB4BA>Damage:</color> <color=#FFFFFF>[DamageModifier]</color> <color=#9FB4BA>Speed:</color> <color=#FFFFFF>[MovementSpeed]</color> <color=#9FB4BA>Cooldown:</color> <color=#FFFFFF>[Cooldown]</color> <color=#9FB4BA>Crit:</color> <color=#FFFFFF>[CritChance]</color>", "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 (<b>, <color=...>, etc). Edit here or via the in-game settings window (F10 by default).");
ShowWeaponsSection = config.Bind<bool>("Sections", "ShowWeapons", true, "Show the Weapons line at the bottom of the overlay.");
ShowPassivesSection = config.Bind<bool>("Sections", "ShowPassives", true, "Show the Passives line at the bottom of the overlay.");
ShowItemsSection = config.Bind<bool>("Sections", "ShowItems", true, "Show the Items line at the bottom of the overlay.");
ShowWeaponStatsSection = config.Bind<bool>("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<bool>("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<bool>("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<int>("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 == "<color=#9FB4BA>Time:</color> <color=#FFFFFF>[matchTime]</color> <color=#9FB4BA>HP:</color> <color=#FFFFFF>[currentHealth]/[maxHealthCurrent] ([healthFraction])</color>\n\n<color=#9FB4BA>DPS (10s):</color> <color=#FFFFFF>[dps]</color> <color=#9FB4BA>Kills/min:</color> <color=#FFFFFF>[kpm]</color>\n<color=#9FB4BA>Combo Dmg:</color> <color=#FFFFFF>[comboDamage]</color>\n<color=#9FB4BA>Kills:</color> <color=#FFFFFF>[kills]</color> <color=#9FB4BA>Total Damage:</color> <color=#FFFFFF>[totalDamage]</color>\n\n<color=#9FB4BA>Damage:</color> <color=#FFFFFF>[DamageModifier]</color> <color=#9FB4BA>Speed:</color> <color=#FFFFFF>[MovementSpeed]</color> <color=#9FB4BA>Cooldown:</color> <color=#FFFFFF>[Cooldown]</color> <color=#9FB4BA>Crit:</color> <color=#FFFFFF>[CritChance]</color>" || KnownPriorDefaults.Contains(Template.Value))
{
Template.Value = "<color=#9FB4BA>Time:</color> <color=#FFFFFF>[matchTime]</color> <color=#9FB4BA>HP:</color> <color=#FFFFFF>[currentHealth]/[maxHealthCurrent] ([healthFraction])</color>\n\n<color=#9FB4BA>DPS (10s):</color> <color=#FFFFFF>[dps]</color> <color=#9FB4BA>Kills/min:</color> <color=#FFFFFF>[kpm]</color>\n<color=#9FB4BA>Combo Dmg:</color> <color=#FFFFFF>[comboDamage]</color>\n<color=#9FB4BA>Kills:</color> <color=#FFFFFF>[kills]</color> <color=#9FB4BA>Total Damage:</color> <color=#FFFFFF>[totalDamage]</color>\n\n<color=#9FB4BA>Damage:</color> <color=#FFFFFF>[DamageModifier]</color> <color=#9FB4BA>Speed:</color> <color=#FFFFFF>[MovementSpeed]</color> <color=#9FB4BA>Cooldown:</color> <color=#FFFFFF>[Cooldown]</color> <color=#9FB4BA>Crit:</color> <color=#FFFFFF>[CritChance]</color>";
}
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("\n<color=#E6C478><b>Weapons</b></color> <color=#FFFFFF>[weapons]</color>");
}
if (settings.ShowWeaponStatsSection.Value)
{
stringBuilder.Append("\n<color=#E6C478><b>DPS / Kills per Weapon</b></color>\n<color=#FFFFFF>[weaponStats]</color>");
}
if (settings.ShowPassivesSection.Value)
{
stringBuilder.Append("\n<color=#E6C478><b>Passives</b></color> <color=#FFFFFF>[passives]</color>");
}
if (settings.ShowItemsSection.Value)
{
stringBuilder.Append("\n<color=#E6C478><b>Items</b></color> <color=#FFFFFF>[items]</color>");
}
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<GUILayoutOption>());
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<GUILayoutOption>());
}
}
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 = $"<color={arg}><b>{count}</b></color>";
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<GUILayoutOption>());
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<GUILayoutOption>());
settings.OverlayVisible.Value = GUILayout.Toggle(settings.OverlayVisible.Value, "Overlay Visible", Array.Empty<GUILayoutOption>());
settings.DockToObjectiveBanner.Value = GUILayout.Toggle(settings.DockToObjectiveBanner.Value, "Dock underneath the \"Find the boss's lair\" objective banner", Array.Empty<GUILayoutOption>());
if (DpsMeterHook.IsPresent)
{
settings.DockToDpsMeter.Value = GUILayout.Toggle(settings.DockToDpsMeter.Value, "Dock above the DpsMeter window (takes priority over the objective banner)", Array.Empty<GUILayoutOption>());
}
settings.ColorizeStatValues.Value = GUILayout.Toggle(settings.ColorizeStatValues.Value, "Colorize values (damage red, HP green, utility teal, kills gold)", Array.Empty<GUILayoutOption>());
settings.ShowChoiceCounters.Value = GUILayout.Toggle(settings.ShowChoiceCounters.Value, "Show Rerolls/Skips/Bans left on the \"Make a choice\" screen", Array.Empty<GUILayoutOption>());
GUILayout.Space(6f);
GUILayout.Label("Sections", headerStyle, Array.Empty<GUILayoutOption>());
settings.ShowWeaponsSection.Value = GUILayout.Toggle(settings.ShowWeaponsSection.Value, "Weapons", Array.Empty<GUILayoutOption>());
settings.ShowWeaponStatsSection.Value = GUILayout.Toggle(settings.ShowWeaponStatsSection.Value, "DPS / Kills per Weapon", Array.Empty<GUILayoutOption>());
settings.ShowPassivesSection.Value = GUILayout.Toggle(settings.ShowPassivesSection.Value, "Passives", Array.Empty<GUILayoutOption>());
settings.ShowItemsSection.Value = GUILayout.Toggle(settings.ShowItemsSection.Value, "Items", Array.Empty<GUILayoutOption>());
GUILayout.Space(6f);
GUILayout.Label("Template", headerStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Use [tokenName] placeholders, e.g. [Health] [MovementSpeed] [JumpsCount] [kills] [weapons]. Supports rich text (<b>, <color=...>).", labelStyle, Array.Empty<GUILayoutOption>());
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<GUILayoutOption>());
if (GUILayout.Button("Apply", Array.Empty<GUILayoutOption>()))
{
settings.Template.Value = templateEditBuffer;
nextRenderTime = 0f;
}
if (GUILayout.Button("Reset to Default", Array.Empty<GUILayoutOption>()))
{
templateEditBuffer = "<color=#9FB4BA>Time:</color> <color=#FFFFFF>[matchTime]</color> <color=#9FB4BA>HP:</color> <color=#FFFFFF>[currentHealth]/[maxHealthCurrent] ([healthFraction])</color>\n\n<color=#9FB4BA>DPS (10s):</color> <color=#FFFFFF>[dps]</color> <color=#9FB4BA>Kills/min:</color> <color=#FFFFFF>[kpm]</color>\n<color=#9FB4BA>Combo Dmg:</color> <color=#FFFFFF>[comboDamage]</color>\n<color=#9FB4BA>Kills:</color> <color=#FFFFFF>[kills]</color> <color=#9FB4BA>Total Damage:</color> <color=#FFFFFF>[totalDamage]</color>\n\n<color=#9FB4BA>Damage:</color> <color=#FFFFFF>[DamageModifier]</color> <color=#9FB4BA>Speed:</color> <color=#FFFFFF>[MovementSpeed]</color> <color=#9FB4BA>Cooldown:</color> <color=#FFFFFF>[Cooldown]</color> <color=#9FB4BA>Crit:</color> <color=#FFFFFF>[CritChance]</color>";
settings.Template.Value = templateEditBuffer;
nextRenderTime = 0f;
}
GUILayout.EndHorizontal();
GUILayout.Space(10f);
GUILayout.Label("Display", headerStyle, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
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<GUILayoutOption>()));
GUILayout.Label(settings.FontSize.Value.ToString(), labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) });
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
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<GUILayoutOption>());
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<GUILayoutOption>());
GUILayout.Label($"Toggle this window: {settings.ToggleSettingsKey.Value}", labelStyle, Array.Empty<GUILayoutOption>());
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<GUILayoutOption>());
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<UpdateCheckResult>)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();
}
}
}