Decompiled source of DebugHUD v1.0.2

AGDDebugHUD.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Character;
using DisputeLib;
using HarmonyLib;
using Player;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AGDDebugHUD")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d64b7691c3c7461419fce52522e421ee733440f6")]
[assembly: AssemblyProduct("AGDDebugHUD")]
[assembly: AssemblyTitle("AGDDebugHUD")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AGDDebugHUD;

[HarmonyPatch]
public static class DebugHUDInjector
{
	[HarmonyPatch(typeof(GameSingleton), "Awake")]
	[HarmonyPostfix]
	private static void InjectDebugHUD()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		if (!((Object)(object)GameObject.Find("AGD_DebugHUD") != (Object)null))
		{
			GameObject val = new GameObject("AGD_DebugHUD");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<DebugHUDBehaviour>();
			Debug.Log((object)"[[AGDDebugHUD]] Debug HUD injected successfully.");
		}
	}
}
public class DebugHUDBehaviour : MonoBehaviour
{
	private Canvas _canvas;

	private GameObject _panel;

	private PlayerController _localPlayer;

	private CoreCharacterController _characterController;

	private CharacterMovementController _characterMovementController;

	private RagdollController _characterRagdollController;

	private Stopwatch HUDTimeStopwatch = new Stopwatch();

	public double HUDTimeMs;

	private void Awake()
	{
		if (!Plugin.EnabledConfig.Value)
		{
			((Behaviour)this).enabled = false;
			return;
		}
		RegisterDefaultLines();
		CreateUI();
	}

	private void EnsureControllers()
	{
		if (((Object)(object)_localPlayer != (Object)null && (Object)(object)_characterController != (Object)null && (Object)(object)_characterMovementController != (Object)null && (Object)(object)_characterRagdollController != (Object)null) || (Object)(object)SessionManager.Instance == (Object)null)
		{
			return;
		}
		_localPlayer = SessionManager.Instance.LocalPlayer;
		if (!((Object)(object)_localPlayer == (Object)null))
		{
			_characterController = _localPlayer.serverSpawnedCharacter;
			if ((Object)(object)_characterController != (Object)null)
			{
				_characterMovementController = ((Component)_characterController).GetComponent<CharacterMovementController>();
				_characterRagdollController = _characterController.Model.RagdollController;
			}
		}
	}

	private void RegisterDefaultLines()
	{
		if (Plugin.EnableGameSectionConfig.Value)
		{
			DebugHUDAPI.Header header = DebugHUDAPI.RegisterHeader("--- Game ---");
			if (Plugin.EnableFPSConfig.Value)
			{
				DebugHUDAPI.RegisterCustomLine("FPS", () => $"Frame time: {Time.deltaTime * 1000f:F1}ms FPS: {1f / Time.deltaTime:F2}", header);
			}
			if (Plugin.EnableHUDFPSConfig.Value)
			{
				DebugHUDAPI.RegisterCustomLine("HUD Time", () => $"HUD time: {HUDTimeMs:F3}ms FPS impact: {1.0 / ((double)Time.deltaTime - HUDTimeMs / 1000.0) - (double)(1f / Time.deltaTime):F2}", header);
			}
		}
		if (Plugin.EnableNetworkSectionConfig.Value)
		{
			DebugHUDAPI.Header header2 = DebugHUDAPI.RegisterHeader("--- Network ---");
			if (Plugin.EnablePingConfig.Value)
			{
				DebugHUDAPI.RegisterCustomLine("Ping", delegate
				{
					EnsureControllers();
					return ((Object)(object)_localPlayer == (Object)null) ? null : $"Ping: {_localPlayer.CurrentPing.Value}";
				}, header2);
			}
		}
		if (Plugin.EnableMovementSectionConfig.Value)
		{
			DebugHUDAPI.Header header3 = DebugHUDAPI.RegisterHeader("--- Movement ---");
			if (Plugin.EnableVelocityConfig.Value)
			{
				DebugHUDAPI.RegisterCustomLine("Velocity", delegate
				{
					//IL_001c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_004c: Unknown result type (might be due to invalid IL or missing references)
					//IL_005a: Unknown result type (might be due to invalid IL or missing references)
					EnsureControllers();
					if ((Object)(object)_characterMovementController == (Object)null)
					{
						return (string)null;
					}
					Vector3 velocity = _characterMovementController.Velocity;
					return $"Velocity: {((Vector3)(ref velocity)).magnitude:F2} m/s (X:{velocity.x:F2} Y:{velocity.y:F2} Z:{velocity.z:F2})";
				}, header3);
			}
			if (Plugin.EnablePositionConfig.Value)
			{
				DebugHUDAPI.RegisterCustomLine("Position", delegate
				{
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0037: 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)
					EnsureControllers();
					if ((Object)(object)_characterMovementController == (Object)null)
					{
						return (string)null;
					}
					Vector3 position = ((Component)_characterMovementController).transform.position;
					return $"Position: ({position.x:F2}, {position.y:F2}, {position.z:F2})";
				}, header3);
			}
		}
		if (Plugin.EnablePhysicsSectionConfig.Value)
		{
			DebugHUDAPI.Header header4 = DebugHUDAPI.RegisterHeader("--- Physics ---");
			if (Plugin.EnableRagdollStateConfig.Value)
			{
				DebugHUDAPI.RegisterCustomLine("Ragdoll State", delegate
				{
					EnsureControllers();
					return ((Object)(object)_characterRagdollController == (Object)null) ? null : $"IsRagdoll: {_characterRagdollController.IsRagdollNetworked.Value}  TimeInRagdollState: {_characterRagdollController.TimeInRagdollState.Elapsed}";
				}, header4);
			}
		}
		if (!Plugin.EnableStatusSectionConfig.Value)
		{
			return;
		}
		DebugHUDAPI.Header header5 = DebugHUDAPI.RegisterHeader("--- Status ---");
		if (Plugin.EnableStateConfig.Value)
		{
			DebugHUDAPI.RegisterCustomLine("State", delegate
			{
				EnsureControllers();
				return ((Object)(object)_characterController == (Object)null) ? null : string.Format("Grounded: {0}  Aiming: {1}  Alive: {2}  NoClip: {3}", ((Object)(object)_characterMovementController != (Object)null) ? _characterMovementController.IsGroundedNetworked.Value.ToString() : "?", _characterController.IsAiming, _characterController.IsAlive, _localPlayer.NoClip);
			}, header5);
		}
		if (!Plugin.EnableStatusEffectsConfig.Value)
		{
			return;
		}
		DebugHUDAPI.RegisterCustomLine("Status Effects", delegate
		{
			EnsureControllers();
			if ((Object)(object)_characterController == (Object)null)
			{
				return (string)null;
			}
			StatusEffectController statusEffectController = _characterController.statusEffectController;
			if ((Object)(object)statusEffectController != (Object)null && statusEffectController.StatusEffects != null)
			{
				string[] array = (from e in (IEnumerable<StatusEffectData>)statusEffectController.StatusEffects
					where e != null
					select ((object)Unsafe.As<StatusEffect, StatusEffect>(ref e.Effect)/*cast due to .constrained prefix*/).ToString()).ToArray();
				return string.Format("Status Effects ({0}): {1}", array.Length, (array.Length != 0) ? string.Join(", ", array) : "none");
			}
			return "Status Effects (0): none";
		}, header5);
	}

	private void CreateUI()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		//IL_00d6: 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_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
		_canvas.renderMode = (RenderMode)0;
		_canvas.sortingOrder = 32767;
		CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
		obj.uiScaleMode = (ScaleMode)1;
		obj.referenceResolution = new Vector2(1920f, 1080f);
		((Component)this).gameObject.AddComponent<GraphicRaycaster>();
		_panel = new GameObject("Panel", new Type[4]
		{
			typeof(RectTransform),
			typeof(Image),
			typeof(VerticalLayoutGroup),
			typeof(ContentSizeFitter)
		});
		_panel.transform.SetParent(((Component)this).transform, false);
		RectTransform component = _panel.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0f, 1f);
		component.anchorMax = new Vector2(0f, 1f);
		component.pivot = new Vector2(0f, 1f);
		component.anchoredPosition = new Vector2(10f, -10f);
		((Graphic)_panel.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.6f);
		VerticalLayoutGroup component2 = _panel.GetComponent<VerticalLayoutGroup>();
		((LayoutGroup)component2).padding = new RectOffset(10, 10, 6, 6);
		((HorizontalOrVerticalLayoutGroup)component2).spacing = 2f;
		((LayoutGroup)component2).childAlignment = (TextAnchor)0;
		((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
		((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true;
		ContentSizeFitter component3 = _panel.GetComponent<ContentSizeFitter>();
		component3.horizontalFit = (FitMode)2;
		component3.verticalFit = (FitMode)2;
		DebugHUDAPI.Initialize(_panel, 14f);
	}

	private void Update()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown(Plugin.ToggleKeyConfig.Value))
		{
			_panel.SetActive(!_panel.activeSelf);
		}
		if (_panel.activeSelf)
		{
			HUDTimeStopwatch.Restart();
			DebugHUDAPI.RefreshAll();
			HUDTimeStopwatch.Stop();
			HUDTimeMs = HUDTimeStopwatch.Elapsed.TotalMilliseconds;
		}
	}
}
public static class DebugHUDAPI
{
	public class CustomLineEntry
	{
		public enum State
		{
			Enabled,
			Frozen,
			Disabled
		}

		public string Label;

		public TextMeshProUGUI Tmp;

		public Func<string> Getter;

		public State CurrentState;
	}

	public class Header
	{
		public string Label;

		internal TextMeshProUGUI Tmp;
	}

	private static readonly Header _defaultHeader = new Header();

	private static readonly Dictionary<Header, List<CustomLineEntry>> _lines = new Dictionary<Header, List<CustomLineEntry>>();

	private static readonly Dictionary<string, Header> _headerByLabel = new Dictionary<string, Header>();

	private static readonly Dictionary<string, CustomLineEntry> _entryByLabel = new Dictionary<string, CustomLineEntry>();

	private static GameObject _panel;

	private static float _fontSize;

	private static bool _initialized;

	public static void RegisterCustomLine(string label, Func<string> getter, Header header = null)
	{
		if (header == null)
		{
			header = _defaultHeader;
		}
		Header header2 = null;
		if (_entryByLabel.TryGetValue(label, out var value))
		{
			value.Getter = getter;
			foreach (KeyValuePair<Header, List<CustomLineEntry>> line in _lines)
			{
				if (line.Value.Remove(value))
				{
					header2 = line.Key;
					break;
				}
			}
		}
		else
		{
			value = new CustomLineEntry
			{
				Label = label,
				Getter = getter
			};
			_entryByLabel[label] = value;
		}
		if (!_lines.ContainsKey(header))
		{
			_lines[header] = new List<CustomLineEntry>();
		}
		_lines[header].Add(value);
		if (_initialized && (Object)(object)_panel != (Object)null)
		{
			if ((Object)(object)value.Tmp == (Object)null)
			{
				value.Tmp = CreateLineInternal(_panel, label, _fontSize, isHeader: false);
			}
			else if (header2 != null && header2 != header)
			{
				Object.Destroy((Object)(object)((Component)value.Tmp).gameObject);
				value.Tmp = CreateLineInternal(_panel, label, _fontSize, isHeader: false);
			}
		}
	}

	public static Header RegisterHeader(string label)
	{
		if (_headerByLabel.TryGetValue(label, out var value))
		{
			return value;
		}
		value = new Header
		{
			Label = label
		};
		_headerByLabel[label] = value;
		_lines[value] = new List<CustomLineEntry>();
		if (_initialized && (Object)(object)_panel != (Object)null)
		{
			value.Tmp = CreateLineInternal(_panel, label, _fontSize, isHeader: true);
		}
		return value;
	}

	public static void EnableLine(string label)
	{
		SetLineState(label, CustomLineEntry.State.Enabled);
	}

	public static void DisableLine(string label)
	{
		SetLineState(label, CustomLineEntry.State.Disabled);
	}

	public static void FreezeLine(string label)
	{
		SetLineState(label, CustomLineEntry.State.Frozen);
	}

	public static void SetLineState(string label, CustomLineEntry.State state)
	{
		if (_entryByLabel.TryGetValue(label, out var value))
		{
			value.CurrentState = state;
		}
	}

	public static void Initialize(GameObject panel, float fontSize)
	{
		_panel = panel;
		_fontSize = fontSize;
		_initialized = true;
		foreach (KeyValuePair<Header, List<CustomLineEntry>> line in _lines)
		{
			Header key = line.Key;
			if (key != _defaultHeader && (Object)(object)key.Tmp == (Object)null)
			{
				key.Tmp = CreateLineInternal(panel, key.Label, fontSize, isHeader: true);
			}
			foreach (CustomLineEntry item in line.Value)
			{
				if ((Object)(object)item.Tmp == (Object)null)
				{
					item.Tmp = CreateLineInternal(panel, item.Label, fontSize, isHeader: false);
				}
			}
		}
	}

	public static void RefreshAll()
	{
		foreach (KeyValuePair<Header, List<CustomLineEntry>> line in _lines)
		{
			Header key = line.Key;
			if (key != _defaultHeader && (Object)(object)key.Tmp != (Object)null)
			{
				((TMP_Text)key.Tmp).text = key.Label;
			}
			foreach (CustomLineEntry item in line.Value)
			{
				if ((Object)(object)item.Tmp == (Object)null)
				{
					continue;
				}
				switch (item.CurrentState)
				{
				case CustomLineEntry.State.Disabled:
					((Component)item.Tmp).gameObject.SetActive(false);
					continue;
				case CustomLineEntry.State.Frozen:
					continue;
				}
				string text = item.Getter?.Invoke();
				bool flag = text != null;
				if (flag)
				{
					((TMP_Text)item.Tmp).text = text;
				}
				((Component)item.Tmp).gameObject.SetActive(flag);
			}
		}
	}

	private static TextMeshProUGUI CreateLineInternal(GameObject parent, string name, float fontSize, bool isHeader)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[2]
		{
			typeof(RectTransform),
			typeof(TextMeshProUGUI)
		});
		val.transform.SetParent(parent.transform, false);
		TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
		((TMP_Text)component).text = name;
		((TMP_Text)component).fontSize = fontSize;
		((TMP_Text)component).fontStyle = (FontStyles)(isHeader ? 1 : 0);
		((Graphic)component).color = (Color)(isHeader ? new Color(1f, 0.85f, 0.3f) : Color.white);
		((Graphic)component).raycastTarget = false;
		val.AddComponent<LayoutElement>().minHeight = fontSize + 4f;
		return component;
	}
}
[BepInPlugin("com.unii.debugHud", "Debug HUD", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	public static ConfigEntry<bool> EnabledConfig;

	public static ConfigEntry<KeyCode> ToggleKeyConfig;

	public static ConfigEntry<bool> EnableGameSectionConfig;

	public static ConfigEntry<bool> EnableFPSConfig;

	public static ConfigEntry<bool> EnableHUDFPSConfig;

	public static ConfigEntry<bool> EnableNetworkSectionConfig;

	public static ConfigEntry<bool> EnablePingConfig;

	public static ConfigEntry<bool> EnableMovementSectionConfig;

	public static ConfigEntry<bool> EnableVelocityConfig;

	public static ConfigEntry<bool> EnablePositionConfig;

	public static ConfigEntry<bool> EnablePhysicsSectionConfig;

	public static ConfigEntry<bool> EnableRagdollStateConfig;

	public static ConfigEntry<bool> EnableStatusSectionConfig;

	public static ConfigEntry<bool> EnableStateConfig;

	public static ConfigEntry<bool> EnableStatusEffectsConfig;

	private void Awake()
	{
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		EnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable the Debug HUD overlay.");
		ToggleKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)284, "Key to toggle the debug HUD on/off.");
		EnableGameSectionConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableGameSection", true, "Enable the values under the Game header. Overrides EnableFPS and EnableHUDFPS.");
		EnableFPSConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableFPS", true, "Enable showing FPS and frame time under the Game header.");
		EnableHUDFPSConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableHUDFPS", true, "Enable showing HUD specific frame time and FPS impact under the Game header.");
		EnableNetworkSectionConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableNetworkSection", true, "Enable the values under the Network header. Overrides EnablePing.");
		EnablePingConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnablePing", true, "Enable showing Ping under the Network header.");
		EnableMovementSectionConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableMovementSection", true, "Enable the values under the Movement header. Overrides EnableVelocity and EnablePosition.");
		EnableVelocityConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableVelocity", true, "Enable showing player velocity under the Movement header.");
		EnablePositionConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnablePosition", true, "Enable showing player coordinates under the Movement header.");
		EnablePhysicsSectionConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnablePhysicsSection", true, "Enable the values under the Physics header. Overrides EnableRagdollState.");
		EnableRagdollStateConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableRagdollState", true, "Enable showing the player's ragdoll state under the Physics header.");
		EnableStatusSectionConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableStatusSection", true, "Enable the values under the Status header. Overrides EnableState and EnableStatusEffects.");
		EnableStateConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableState", true, "Enable showing the player's current state under the Status header.");
		EnableStatusEffectsConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultLines", "EnableStatusEffects", true, "Enable showing active status effects under the Status header.");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Debug HUD plugin loaded successfully!");
		new Harmony("com.unii.debugHud").PatchAll();
	}
}