Decompiled source of DPSBoard v1.0.0

Mods/DPSBoard.dll

Decompiled a week ago
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();
			}
		}
	}
}