Decompiled source of FPSCounter v1.0.7

FPSCounter.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
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(FPSCounter), "FPS Counter", "1.0.7", "DiumStream", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyMetadata("NexusModID", "737")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
public class FPSCounter : MelonMod
{
	private GameObject? _uiRoot;

	private Text? _fpsText;

	private RectTransform? _bgRect;

	private float _smoothedFps;

	private float _currentFps;

	private readonly char[] _fpsBuffer = new char[8];

	private const string FpsPrefix = "FPS: ";

	public override void OnInitializeMelon()
	{
		try
		{
			Application.targetFrameRate = -1;
			Config.Load();
			Config.OnSettingsUpdated += OnSettingsUpdateReceived;
			InitializeUI();
			OnSettingsUpdateReceived();
			MelonLogger.Msg("FPS Counter initialisé !");
		}
		catch (Exception value)
		{
			MelonLogger.Error($"Erreur initialisation: {value}");
		}
	}

	public override void OnDeinitializeMelon()
	{
		Config.OnSettingsUpdated -= OnSettingsUpdateReceived;
	}

	private void OnSettingsUpdateReceived()
	{
		UpdateUI();
		UpdatePosition();
		if ((Object)(object)_uiRoot != (Object)null)
		{
			_uiRoot.SetActive(Config.Enabled.Value);
		}
	}

	public override void OnPreferencesSaved()
	{
		Config.OnPreferencesSaved();
	}

	private void InitializeUI()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00d6: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: 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_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Expected O, but got Unknown
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			for (int i = 0; i < "FPS: ".Length; i++)
			{
				_fpsBuffer[i] = "FPS: "[i];
			}
			_uiRoot = new GameObject("FPS_Canvas");
			Canvas val = _uiRoot.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.sortingOrder = 9999;
			CanvasScaler val2 = _uiRoot.AddComponent<CanvasScaler>();
			val2.uiScaleMode = (ScaleMode)1;
			val2.referenceResolution = new Vector2(1920f, 1080f);
			GameObject val3 = new GameObject("Background");
			val3.transform.SetParent(_uiRoot.transform);
			_bgRect = val3.AddComponent<RectTransform>();
			RectTransform? bgRect = _bgRect;
			Vector2 anchorMin = (_bgRect.anchorMax = new Vector2(0f, 1f));
			bgRect.anchorMin = anchorMin;
			_bgRect.pivot = new Vector2(0.5f, 0.5f);
			_bgRect.sizeDelta = new Vector2(120f, 40f);
			Image val5 = val3.AddComponent<Image>();
			val5.sprite = MakeRoundedSprite(16);
			val5.type = (Type)1;
			((Graphic)val5).color = new Color(0f, 0f, 0f, 0.7f);
			GameObject val6 = new GameObject("FPS_Text");
			val6.transform.SetParent(val3.transform);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchoredPosition = Vector2.zero;
			anchorMin = (val7.anchorMax = new Vector2(0.5f, 0.5f));
			val7.anchorMin = anchorMin;
			val7.pivot = new Vector2(0.5f, 0.5f);
			val7.sizeDelta = new Vector2(200f, 50f);
			_fpsText = val6.AddComponent<Text>();
			_fpsText.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			_fpsText.alignment = (TextAnchor)4;
			((Graphic)_fpsText).raycastTarget = false;
			Object.DontDestroyOnLoad((Object)(object)_uiRoot);
		}
		catch (Exception ex)
		{
			MelonLogger.Error($"Erreur création UI: {ex}\n{ex.StackTrace}");
		}
	}

	private Sprite MakeRoundedSprite(int radius)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		int num = radius * 2 + 2;
		Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
		Color32 val2 = default(Color32);
		((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
		Color32 val3 = default(Color32);
		((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = ((j < radius) ? (radius - j) : (j - (num - radius - 1)));
				float num3 = ((i < radius) ? (radius - i) : (i - (num - radius - 1)));
				if (num2 < 0f)
				{
					num2 = 0f;
				}
				if (num3 < 0f)
				{
					num3 = 0f;
				}
				float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
				val.SetPixel(j, i, Color32.op_Implicit((num4 > (float)radius) ? val2 : val3));
			}
		}
		val.Apply();
		return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 1u, (SpriteMeshType)0, new Vector4((float)radius, (float)radius, (float)radius, (float)radius));
	}

	private void UpdateUI()
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_fpsText == (Object)null) && !((Object)(object)_bgRect == (Object)null))
		{
			_fpsText.fontSize = Config.FontSize.Value;
			((Graphic)_fpsText).color = Config.ColorValue.Value;
			_bgRect.sizeDelta = new Vector2(Mathf.Clamp(_fpsText.preferredWidth + 20f, 100f, 300f), 40f);
		}
	}

	private void UpdatePosition()
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_bgRect == (Object)null))
		{
			_bgRect.anchoredPosition = new Vector2(Mathf.Round(Config.FpsPosX.Value) + 100f, Mathf.Round(Config.FpsPosY.Value));
		}
	}

	public override void OnUpdate()
	{
		Application.targetFrameRate = -1;
		if ((Object)(object)_uiRoot != (Object)null && Config.Enabled.Value && (Object)(object)_fpsText != (Object)null)
		{
			_currentFps = 1f / Time.unscaledDeltaTime;
			_smoothedFps = Mathf.Lerp(_smoothedFps, _currentFps, Config.SmoothingFactor.Value);
			int num = Mathf.RoundToInt(Mathf.Min(_smoothedFps, 999f));
			int length = "FPS: ".Length;
			if (num >= 100)
			{
				_fpsBuffer[length++] = (char)(48 + num / 100);
				_fpsBuffer[length++] = (char)(48 + num % 100 / 10);
				_fpsBuffer[length++] = (char)(48 + num % 10);
			}
			else if (num >= 10)
			{
				_fpsBuffer[length++] = (char)(48 + num / 10);
				_fpsBuffer[length++] = (char)(48 + num % 10);
			}
			else
			{
				_fpsBuffer[length++] = (char)(48 + num);
			}
			_fpsText.text = new string(_fpsBuffer, 0, length);
		}
	}

	public override void OnSceneWasInitialized(int buildIndex, string sceneName)
	{
		if ((Object)(object)_uiRoot == (Object)null)
		{
			InitializeUI();
			OnSettingsUpdateReceived();
		}
	}
}
public static class Config
{
	public static MelonPreferences_Category Category { get; private set; }

	public static MelonPreferences_Entry<Color> ColorValue { get; private set; }

	public static MelonPreferences_Entry<int> FontSize { get; private set; }

	public static MelonPreferences_Entry<bool> Enabled { get; private set; }

	public static MelonPreferences_Entry<float> SmoothingFactor { get; private set; }

	public static MelonPreferences_Entry<float> FpsPosX { get; private set; }

	public static MelonPreferences_Entry<float> FpsPosY { get; private set; }

	public static event Action? OnSettingsUpdated;

	public static void Load()
	{
		try
		{
			InitializeCategory();
			ConvertLegacyConfig();
			ValidateSettings();
			MelonLogger.Msg("Configuration chargée avec succès !");
		}
		catch (Exception value)
		{
			MelonLogger.Error($"Erreur lors du chargement de la config: {value}");
		}
	}

	private static void InitializeCategory()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		Category = MelonPreferences.CreateCategory("FPSCounter_Visuals", "Paramètres visuels");
		ColorValue = Category.CreateEntry<Color>("ColorValue", Color.white, "Couleur du texte", "Contrôle la couleur RGBA du compteur", false, false, (ValueValidator)null, (string)null);
		FontSize = Category.CreateEntry<int>("FontSize", 24, "Taille de police", "Taille en pixels du texte", false, false, (ValueValidator)null, (string)null);
		Enabled = Category.CreateEntry<bool>("Enabled", true, "Activé", "Activer/désactiver le compteur", false, false, (ValueValidator)null, (string)null);
		SmoothingFactor = Category.CreateEntry<float>("SmoothingFactor", 0.1f, "Lissage", "Fluidité de l'affichage (0.1-1.0)", false, false, (ValueValidator)null, (string)null);
		FpsPosX = Category.CreateEntry<float>("FpsPosX", -40f, "Position X", "Décalage horizontal", false, false, (ValueValidator)null, (string)null);
		FpsPosY = Category.CreateEntry<float>("FpsPosY", -20f, "Position Y", "Décalage vertical", false, false, (ValueValidator)null, (string)null);
	}

	private static void ConvertLegacyConfig()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			MelonPreferences_Entry<string> entry = MelonPreferences.GetEntry<string>("FPSCounter", "TextColorHex");
			Color value = default(Color);
			if (entry != null && ColorUtility.TryParseHtmlString(entry.Value, ref value))
			{
				ColorValue.Value = value;
				((MelonPreferences_Entry)entry).IsHidden = true;
			}
			MelonPreferences_Entry<string> entry2 = MelonPreferences.GetEntry<string>("FPSCounter", "ColorValue");
			if (entry2 != null)
			{
				float result;
				float[] array = (from s in entry2.Value.Trim('[', ']').Split(',')
					select float.TryParse(s.Trim(), out result) ? result : 255f).ToArray();
				if (array.Length >= 4)
				{
					ColorValue.Value = new Color(Mathf.Clamp01(array[0] / 255f), Mathf.Clamp01(array[1] / 255f), Mathf.Clamp01(array[2] / 255f), Mathf.Clamp01(array[3] / 255f));
				}
				((MelonPreferences_Entry)entry2).IsHidden = true;
			}
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("Échec de la conversion des anciens paramètres: " + ex.Message);
		}
	}

	public static void OnPreferencesSaved()
	{
		ValidateSettings();
		Config.OnSettingsUpdated?.Invoke();
	}

	private static void ValidateSettings()
	{
		if (SmoothingFactor.Value < 0.1f || SmoothingFactor.Value > 1f)
		{
			SmoothingFactor.Value = Mathf.Clamp(SmoothingFactor.Value, 0.1f, 1f);
			Category.SaveToFile(true);
		}
		FpsPosX.Value = Mathf.Clamp(FpsPosX.Value, -1920f, 1920f);
		FpsPosY.Value = Mathf.Clamp(FpsPosY.Value, -1080f, 1080f);
	}
}
public static class PluginInfo
{
	public const string PLUGIN_AUTHOR = "DiumStream";

	public const string PLUGIN_NAME = "FPS Counter";

	public const string PLUGIN_VERSION = "1.0.7";
}