Decompiled source of Performance v1.0.0

Performance.dll

Decompiled 2 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Performance")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Performance")]
[assembly: AssemblyTitle("Performance")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("celunar.performance", "Performance", "1.5.0")]
public class Plugin : BaseUnityPlugin
{
	private struct Utilization
	{
		public uint gpu;

		public uint memory;
	}

	private float fps;

	private int frames;

	private float fpsTimer;

	private uint gpuLoad;

	private uint gpuTemp;

	private float gpuTimer;

	private bool nvmlAvailable;

	private IntPtr gpuDevice;

	private Type tmpType;

	private Type fontAssetType;

	private Type canvasType;

	private Component fpsText;

	private Component gpuText;

	private Component tempText;

	private object peakFont;

	private Component peakSample;

	private const float TextSize = 13f;

	[DllImport("nvml.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern int nvmlInit_v2();

	[DllImport("nvml.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern int nvmlDeviceGetHandleByIndex_v2(uint index, out IntPtr device);

	[DllImport("nvml.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern int nvmlDeviceGetTemperature(IntPtr device, uint sensorType, out uint temperature);

	[DllImport("nvml.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern int nvmlDeviceGetUtilizationRates(IntPtr device, out Utilization utilization);

	private void Awake()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Performance 1.5.0 loaded!");
		FindTypes();
		FindPeakAssets();
		CreateUI();
		InitGPU();
	}

	private void FindTypes()
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			if (tmpType == null)
			{
				tmpType = assembly.GetType("TMPro.TextMeshProUGUI");
			}
			if (fontAssetType == null)
			{
				fontAssetType = assembly.GetType("TMPro.TMP_FontAsset");
			}
			if (canvasType == null)
			{
				canvasType = assembly.GetType("UnityEngine.Canvas");
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("TMP: " + (tmpType != null)));
		((BaseUnityPlugin)this).Logger.LogInfo((object)("FontAsset: " + (fontAssetType != null)));
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Canvas: " + (canvasType != null)));
	}

	private void FindPeakAssets()
	{
		if (fontAssetType != null)
		{
			Object[] array = Resources.FindObjectsOfTypeAll(fontAssetType);
			Object[] array2 = array;
			foreach (Object val in array2)
			{
				if (!(val == (Object)null) && val.name == "DarumaDropOne-Regular SDF")
				{
					peakFont = val;
					((BaseUnityPlugin)this).Logger.LogInfo((object)("PEAK FONT FOUND: " + val.name));
					break;
				}
			}
		}
		if (tmpType == null)
		{
			return;
		}
		Object[] array3 = Resources.FindObjectsOfTypeAll(tmpType);
		Object[] array4 = array3;
		foreach (Object val2 in array4)
		{
			Component val3 = (Component)(object)((val2 is Component) ? val2 : null);
			if ((Object)(object)val3 == (Object)null)
			{
				continue;
			}
			try
			{
				PropertyInfo property = tmpType.GetProperty("font");
				if (property == null)
				{
					continue;
				}
				object value = property.GetValue(val3, null);
				if (value != null)
				{
					string text = value.GetType().GetProperty("name")?.GetValue(value, null) as string;
					if (!(text != "DarumaDropOne-Regular SDF"))
					{
						peakSample = val3;
						((BaseUnityPlugin)this).Logger.LogInfo((object)("PEAK TEXT SAMPLE FOUND: " + ((Object)val3.gameObject).name));
						break;
					}
				}
			}
			catch
			{
			}
		}
		if ((Object)(object)peakSample == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find PEAK TMP sample.");
		}
	}

	private void CreateUI()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		if (tmpType == null || canvasType == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Required Unity/TMP types not found.");
			return;
		}
		GameObject val = new GameObject("PerformanceCanvas");
		Object.DontDestroyOnLoad((Object)(object)val);
		Component obj = val.AddComponent(canvasType);
		Type type = FindType("UnityEngine.RenderMode");
		if (type != null)
		{
			SetProperty(obj, "renderMode", Enum.Parse(type, "ScreenSpaceOverlay"));
		}
		SetProperty(obj, "sortingOrder", 9999);
		fpsText = CreateText(val.transform, "fps");
		gpuText = CreateText(val.transform, "gpu");
		tempText = CreateText(val.transform, "gpu temp");
		SetPosition(fpsText, -12f, -10f);
		SetPosition(gpuText, -12f, -27f);
		SetPosition(tempText, -12f, -44f);
	}

	private Component CreateText(Transform parent, string objectName)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		GameObject val = new GameObject("Performance_" + objectName);
		val.transform.SetParent(parent, false);
		Component val2 = val.AddComponent(tmpType);
		ApplyPeakStyle(val2);
		SetProperty(val2, "text", objectName);
		SetProperty(val2, "raycastTarget", false);
		SetupRect(val);
		return val2;
	}

	private void ApplyPeakStyle(Component target)
	{
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		if (peakFont != null)
		{
			SetProperty(target, "font", peakFont);
		}
		if ((Object)(object)peakSample != (Object)null)
		{
			CopyProperty(peakSample, target, "fontSharedMaterial");
			CopyProperty(peakSample, target, "fontMaterial");
			CopyProperty(peakSample, target, "fontStyle");
			CopyProperty(peakSample, target, "fontWeight");
			CopyProperty(peakSample, target, "characterSpacing");
			CopyProperty(peakSample, target, "wordSpacing");
			CopyProperty(peakSample, target, "lineSpacing");
			CopyProperty(peakSample, target, "paragraphSpacing");
			CopyProperty(peakSample, target, "color");
			CopyProperty(peakSample, target, "enableVertexGradient");
			CopyProperty(peakSample, target, "enableExtraPadding");
		}
		else
		{
			SetProperty(target, "color", (object)new Color(0.88f, 0.84f, 0.75f, 1f));
		}
		SetProperty(target, "fontSize", 13f);
		SetProperty(target, "enableAutoSizing", false);
		SetProperty(target, "enableWordWrapping", false);
		Type type = FindType("TMPro.TextAlignmentOptions");
		if (type != null)
		{
			try
			{
				object value = Enum.Parse(type, "TopRight");
				SetProperty(target, "alignment", value);
			}
			catch
			{
			}
		}
	}

	private void CopyProperty(Component source, Component target, string propertyName)
	{
		try
		{
			PropertyInfo property = tmpType.GetProperty(propertyName);
			if (!(property == null) && property.CanRead && property.CanWrite)
			{
				object value = property.GetValue(source, null);
				property.SetValue(target, value, null);
			}
		}
		catch
		{
		}
	}

	private void SetupRect(GameObject obj)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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)
		Type type = FindType("UnityEngine.RectTransform");
		if (!(type == null))
		{
			Component component = obj.GetComponent(type);
			if (!((Object)(object)component == (Object)null))
			{
				SetProperty(component, "anchorMin", (object)new Vector2(1f, 1f));
				SetProperty(component, "anchorMax", (object)new Vector2(1f, 1f));
				SetProperty(component, "pivot", (object)new Vector2(1f, 1f));
				SetProperty(component, "sizeDelta", (object)new Vector2(190f, 22f));
			}
		}
	}

	private void SetPosition(Component text, float x, float y)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)text == (Object)null)
		{
			return;
		}
		Type type = FindType("UnityEngine.RectTransform");
		if (!(type == null))
		{
			Component component = text.gameObject.GetComponent(type);
			if (!((Object)(object)component == (Object)null))
			{
				SetProperty(component, "anchoredPosition", (object)new Vector2(x, y));
			}
		}
	}

	private void SetText(Component text, string value)
	{
		if (!((Object)(object)text == (Object)null))
		{
			SetProperty(text, "text", value);
		}
	}

	private void SetProperty(object obj, string propertyName, object value)
	{
		if (obj == null)
		{
			return;
		}
		try
		{
			PropertyInfo property = obj.GetType().GetProperty(propertyName);
			if (!(property == null) && property.CanWrite)
			{
				property.SetValue(obj, value, null);
			}
		}
		catch
		{
		}
	}

	private Type FindType(string name)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			Type type = assembly.GetType(name);
			if (type != null)
			{
				return type;
			}
		}
		return null;
	}

	private void InitGPU()
	{
		try
		{
			if (nvmlInit_v2() == 0 && nvmlDeviceGetHandleByIndex_v2(0u, out gpuDevice) == 0)
			{
				nvmlAvailable = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"NVIDIA GPU detected.");
			}
		}
		catch
		{
			nvmlAvailable = false;
		}
	}

	private void Update()
	{
		frames++;
		fpsTimer += Time.unscaledDeltaTime;
		if (fpsTimer >= 0.5f)
		{
			fps = (float)frames / fpsTimer;
			frames = 0;
			fpsTimer = 0f;
		}
		gpuTimer += Time.unscaledDeltaTime;
		if (gpuTimer >= 1f)
		{
			gpuTimer = 0f;
			UpdateGPU();
		}
		SetText(fpsText, "fps " + fps.ToString("0"));
		if (nvmlAvailable)
		{
			SetText(gpuText, "gpu " + gpuLoad + "%");
			SetText(tempText, "gpu temp " + gpuTemp + "°c");
		}
		else
		{
			SetText(gpuText, "gpu --");
			SetText(tempText, "gpu temp --");
		}
	}

	private void UpdateGPU()
	{
		if (!nvmlAvailable)
		{
			return;
		}
		try
		{
			if (nvmlDeviceGetTemperature(gpuDevice, 0u, out var temperature) == 0)
			{
				gpuTemp = temperature;
			}
			if (nvmlDeviceGetUtilizationRates(gpuDevice, out var utilization) == 0)
			{
				gpuLoad = utilization.gpu;
			}
		}
		catch
		{
			nvmlAvailable = false;
		}
	}
}