using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using DPSBoard;
using HarmonyLib;
using MelonLoader;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(DPSBoardMod), "DPSBoard", "1.0.0", "rf5860", null)]
[assembly: MelonGame("Alvios", "Vellum")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace DPSBoard;
public class DPSBoardMod : MelonMod
{
internal class DPSEntry
{
public GameObject gameObject;
public TextMeshProUGUI nameText;
public TextMeshProUGUI dpsText;
public PlayerControl player;
private TextMeshProUGUI totalDamageText;
private TextMeshProUGUI chapterDamageText;
private int lastChapterDamage;
public void UpdateStats(float dps)
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)dpsText != (Object)null)
{
int num = (int)dps;
if (num < 1000)
{
((TMP_Text)dpsText).text = num.ToString();
}
else if (num < 1000000)
{
((TMP_Text)dpsText).text = $"{(float)num / 1000f:F1}K";
}
else
{
((TMP_Text)dpsText).text = $"{(float)num / 1000000f:F1}M";
}
}
if ((Object)(object)nameText != (Object)null && (Object)(object)player != (Object)null)
{
((Graphic)nameText).color = GetPlayerColor(player);
}
if (!((Object)(object)player == (Object)null) && player.PStats != null)
{
int num2 = player.PStats.TotalDamage();
int num3 = num2;
if (chapterStartDamage.TryGetValue(player, out var value))
{
num3 = num2 - value;
}
if (num3 > 0)
{
lastChapterDamage = num3;
}
if ((Object)(object)totalDamageText == (Object)null)
{
totalDamageText = CreateStatText(gameObject, "TotalDamage", Color.cyan, 80f);
}
if ((Object)(object)chapterDamageText == (Object)null)
{
chapterDamageText = CreateStatText(gameObject, "ChapterDamage", Color.green, 80f);
}
((TMP_Text)totalDamageText).text = FormatNumber(num2) ?? "";
((TMP_Text)chapterDamageText).text = FormatNumber(lastChapterDamage) ?? "";
}
}
private static TextMeshProUGUI CreateStatText(GameObject parent, string name, Color color, float width)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
val.transform.SetParent(parent.transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.sizeDelta = new Vector2(width, 0f);
TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val3).fontSize = 18f;
((TMP_Text)val3).alignment = (TextAlignmentOptions)516;
((Graphic)val3).color = color;
((TMP_Text)val3).fontStyle = (FontStyles)0;
return val3;
}
private static string FormatNumber(int value)
{
if (value < 1000)
{
return value.ToString();
}
return (value < 1000000) ? $"{(float)value / 1000f:F1}K" : $"{(float)value / 1000000f:F1}M";
}
}
internal static GameObject dpsOverlay;
internal static GameObject dpsContainer;
internal static readonly Dictionary<PlayerControl, DPSEntry> dpsEntries = new Dictionary<PlayerControl, DPSEntry>();
internal static readonly Dictionary<PlayerControl, int> chapterStartDamage = new Dictionary<PlayerControl, int>();
private static float updateTimer;
private const float UPDATE_INTERVAL = 0.5f;
private static bool isVisible;
public override void OnInitializeMelon()
{
MelonLogger.Msg("VellumMod has started!");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
if ((Object)(object)dpsOverlay != (Object)null)
{
Object.Destroy((Object)(object)dpsOverlay);
dpsOverlay = null;
dpsContainer = null;
foreach (DPSEntry value in dpsEntries.Values)
{
if ((Object)(object)value.gameObject != (Object)null)
{
Object.Destroy((Object)(object)value.gameObject);
value.gameObject = null;
value.nameText = null;
value.dpsText = null;
}
}
}
if (isVisible)
{
CreateDPSOverlay();
}
}
public override void OnUpdate()
{
if (Input.GetKeyDown((KeyCode)285))
{
ToggleDPSBoard();
}
UpdateDPSDisplayIfVisible();
}
private static void UpdateDPSDisplayIfVisible()
{
if (isVisible && !((Object)(object)dpsOverlay == (Object)null) && !((updateTimer += Time.deltaTime) < 0.5f))
{
updateTimer = 0f;
UpdateDPSDisplay();
}
}
private static void ToggleDPSBoard()
{
isVisible = !isVisible;
if (isVisible)
{
if ((Object)(object)dpsOverlay == (Object)null)
{
CreateDPSOverlay();
}
dpsOverlay.SetActive(true);
MelonLogger.Msg("DPS Board Enabled");
}
else if ((Object)(object)dpsOverlay != (Object)null)
{
dpsOverlay.SetActive(false);
MelonLogger.Msg("DPS Board Disabled");
}
}
private static void CreateDPSOverlay()
{
CreateMainOverlayCanvas();
GameObject backgroundPanel = CreateBackgroundPanel();
AddTitle(backgroundPanel);
CreateDPSEntryContainer(backgroundPanel);
}
private static void CreateDPSEntryContainer(GameObject backgroundPanel)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
dpsContainer = new GameObject("DPSContainer");
dpsContainer.transform.SetParent(backgroundPanel.transform, false);
RectTransform val = dpsContainer.AddComponent<RectTransform>();
val.anchorMin = new Vector2(0f, 0.05f);
val.anchorMax = new Vector2(1f, 0.9f);
val.offsetMin = new Vector2(10f, 5f);
val.offsetMax = new Vector2(-10f, -5f);
VerticalLayoutGroup val2 = dpsContainer.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)val2).spacing = 5f;
((LayoutGroup)val2).childAlignment = (TextAnchor)1;
((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = false;
((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
}
private static void AddTitle(GameObject backgroundPanel)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Title");
val.transform.SetParent(backgroundPanel.transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = new Vector2(0f, 0.9f);
val2.anchorMax = new Vector2(1f, 1f);
val2.offsetMin = new Vector2(10f, 0f);
val2.offsetMax = new Vector2(-10f, -5f);
TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val3).text = "DPS Board";
((TMP_Text)val3).fontSize = 24f;
((TMP_Text)val3).fontStyle = (FontStyles)1;
((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
((Graphic)val3).color = Color.white;
}
private static GameObject CreateBackgroundPanel()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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)
GameObject val = new GameObject("BackgroundPanel");
val.transform.SetParent(dpsOverlay.transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = new Vector2(0.75f, 0.7f);
val2.anchorMax = new Vector2(0.98f, 0.98f);
val2.offsetMin = Vector2.zero;
val2.offsetMax = Vector2.zero;
Image val3 = val.AddComponent<Image>();
((Graphic)val3).color = new Color(0f, 0f, 0f, 0.8f);
return val;
}
private static void CreateMainOverlayCanvas()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
dpsOverlay = new GameObject("DPSBoardOverlay");
Object.DontDestroyOnLoad((Object)(object)dpsOverlay);
Canvas val = dpsOverlay.AddComponent<Canvas>();
val.renderMode = (RenderMode)0;
val.sortingOrder = 1000;
CanvasScaler val2 = dpsOverlay.AddComponent<CanvasScaler>();
val2.uiScaleMode = (ScaleMode)1;
val2.referenceResolution = new Vector2(1920f, 1080f);
dpsOverlay.AddComponent<GraphicRaycaster>();
}
private static void UpdateDPSDisplay()
{
if (PlayerControl.AllPlayers == null || (Object)(object)dpsContainer == (Object)null)
{
return;
}
HashSet<PlayerControl> hashSet = new HashSet<PlayerControl>(dpsEntries.Keys);
foreach (PlayerControl allPlayer in PlayerControl.AllPlayers)
{
if ((Object)(object)allPlayer != (Object)null && (Object)(object)allPlayer.Net != (Object)null)
{
hashSet.Add(allPlayer);
}
}
List<PlayerControl> playerDPSList = (from player in hashSet
where (Object)(object)player != (Object)null && (Object)(object)player.Net != (Object)null
orderby player.Net.CurrentDPS descending, (player.PStats != null) ? player.PStats.TotalDamage() : 0 descending
select player).ToList();
List<PlayerControl> list = dpsEntries.Keys.Where((PlayerControl player) => !playerDPSList.Contains(player)).ToList();
foreach (PlayerControl item in list)
{
if ((Object)(object)dpsEntries[item].gameObject != (Object)null)
{
Object.Destroy((Object)(object)dpsEntries[item].gameObject);
}
dpsEntries.Remove(item);
}
int num = 0;
foreach (PlayerControl item2 in playerDPSList)
{
if (!dpsEntries.ContainsKey(item2) || (Object)(object)dpsEntries[item2].gameObject == (Object)null)
{
CreateDPSEntry(item2);
}
if (dpsEntries.TryGetValue(item2, out var value))
{
value.UpdateStats(item2.Net.CurrentDPS);
value.gameObject.transform.SetSiblingIndex(num);
}
num++;
}
}
private static void CreateDPSEntry(PlayerControl player)
{
GameObject val = CreateEntryObject(player);
dpsEntries[player] = new DPSEntry
{
gameObject = val,
nameText = CreatePlayerName(player, val),
dpsText = CreateDPSText(val),
player = player
};
}
private static GameObject CreateEntryObject(PlayerControl player)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("DPSEntry_" + player.Username);
val.transform.SetParent(dpsContainer.transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.sizeDelta = new Vector2(0f, 30f);
CreateHorizontalLayout(val);
return val;
}
private static TextMeshProUGUI CreateDPSText(GameObject entryObj)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("DPSValue");
val.transform.SetParent(entryObj.transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.sizeDelta = new Vector2(100f, 0f);
TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val3).text = "0";
((TMP_Text)val3).fontSize = 18f;
((TMP_Text)val3).alignment = (TextAlignmentOptions)516;
((Graphic)val3).color = Color.yellow;
((TMP_Text)val3).fontStyle = (FontStyles)1;
return val3;
}
private static TextMeshProUGUI CreatePlayerName(PlayerControl player, GameObject entryObj)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("PlayerName");
val.transform.SetParent(entryObj.transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.sizeDelta = new Vector2(150f, 0f);
TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val3).text = player.Username;
((TMP_Text)val3).fontSize = 18f;
((TMP_Text)val3).alignment = (TextAlignmentOptions)513;
((Graphic)val3).color = GetPlayerColor(player);
return val3;
}
private static void CreateHorizontalLayout(GameObject entryObj)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
HorizontalLayoutGroup val = entryObj.AddComponent<HorizontalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)val).spacing = 10f;
((LayoutGroup)val).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)val).childControlWidth = false;
((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = true;
((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false;
((LayoutGroup)val).padding = new RectOffset(5, 5, 2, 2);
}
private static Color GetPlayerColor(PlayerControl player)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected I4, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: 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)
object obj;
if (player == null)
{
obj = null;
}
else
{
PlayerActions actions = player.actions;
if (actions == null)
{
obj = null;
}
else
{
AugmentTree core = actions.core;
obj = ((core != null) ? core.Root : null);
}
}
if ((Object)obj == (Object)null)
{
return Color.white;
}
MagicColor magicColor = player.actions.core.Root.magicColor;
MagicColor val = magicColor;
return (Color)((val - 4) switch
{
0 => new Color(1f, 0.3f, 0.3f),
3 => new Color(0.3f, 0.6f, 1f),
2 => new Color(0.3f, 1f, 0.3f),
1 => new Color(1f, 1f, 0.3f),
4 => new Color(0.8f, 0.3f, 1f),
_ => Color.white,
});
}
}
[HarmonyPatch(typeof(GameplayManager), "StartOfGame")]
public static class GameplayManager_StartOfGame_Patch
{
public static void Postfix()
{
DPSBoardMod.dpsEntries.Clear();
DPSBoardMod.chapterStartDamage.Clear();
if (!((Object)(object)DPSBoardMod.dpsOverlay == (Object)null))
{
Object.Destroy((Object)(object)DPSBoardMod.dpsOverlay);
DPSBoardMod.dpsOverlay = null;
DPSBoardMod.dpsContainer = null;
}
}
}
[HarmonyPatch(typeof(CombatTextController), "LateUpdate")]
public static class CombatTextController_LateUpdate_Patch
{
public static void Postfix(CombatTextController __instance)
{
if ((Object)(object)PlayerControl.myInstance != (Object)null && (Object)(object)PlayerControl.myInstance.Net != (Object)null)
{
PlayerControl.myInstance.Net.CurrentDPS = CombatTextController.CurrentDPS;
}
}
}
[HarmonyPatch(typeof(GameRecord), "NextChapter")]
public static class GameRecord_NextChapter_Patch
{
public static void Postfix()
{
if (PlayerControl.AllPlayers == null)
{
return;
}
foreach (PlayerControl allPlayer in PlayerControl.AllPlayers)
{
if (allPlayer?.PStats != null)
{
DPSBoardMod.chapterStartDamage[allPlayer] = allPlayer.PStats.TotalDamage();
}
}
}
}