Decompiled source of PingDisplay v1.1.2

Mods/PingDisplay.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using Photon.Pun;
using PingDisplay;
using RUMBLE.Interactions.InteractionBase;
using RUMBLE.Managers;
using RUMBLE.Players;
using RumbleModUI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(PingDisplayClass), "PingDisplay", "1.1.2", "Baumritter", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(ConsoleColor.DarkGreen)]
[assembly: AssemblyTitle("PingDisplay")]
[assembly: AssemblyDescription("Gets the Ping of Players")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PingDisplay")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3a4c6714-8ec3-4ac3-b179-1f3f81f6fd55")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PingDisplay;

internal class General
{
	internal class Delay
	{
		private readonly bool debug = false;

		private DateTime debugTime;

		private object CRObj;

		public string name;

		private bool Running = false;

		public bool Done = false;

		private DateTime StartTime;

		private double Wait;

		public void Delay_Start(double WaitTime, bool AllowRetrigger = false)
		{
			if (!Running || AllowRetrigger)
			{
				if (Running)
				{
					MelonCoroutines.Stop(CRObj);
				}
				Done = false;
				Wait = WaitTime;
				StartTime = DateTime.Now;
				debugTime = DateTime.Now;
				CRObj = MelonCoroutines.Start(WaitLoop());
				if (debug)
				{
					MelonLogger.Msg(name + " - Started");
				}
			}
		}

		public void Delay_Stop(bool Done = false)
		{
			if (Done)
			{
				this.Done = true;
			}
			if (Running)
			{
				MelonCoroutines.Stop(CRObj);
			}
			Running = false;
			if (debug && Done)
			{
				MelonLogger.Msg(name + " - Done");
			}
			if (debug && !Done)
			{
				MelonLogger.Msg(name + " - Stopped");
			}
			TimeSpan timeSpan = DateTime.Now - debugTime;
			if (debug && Done)
			{
				MelonLogger.Msg(name + " - " + timeSpan.TotalMilliseconds);
			}
		}

		private IEnumerator WaitLoop()
		{
			WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate();
			Running = true;
			while (true)
			{
				if (DateTime.Now >= StartTime.AddSeconds(Wait))
				{
					Delay_Stop(Done: true);
					yield return null;
				}
				yield return waitForFixedUpdate;
			}
		}
	}

	internal class Folders
	{
		private readonly bool debug = true;

		private string UserData = "UserData";

		private string ModFolder;

		private List<string> SubFolders = new List<string>();

		public void SetModFolderCustom(string ModName)
		{
			ModFolder = ModName;
			if (debug)
			{
				MelonLogger.Msg("Set ModFolder to " + ModFolder);
			}
		}

		public void SetModFolderNamespace()
		{
			ModFolder = GetType().Namespace;
			if (debug)
			{
				MelonLogger.Msg("Set ModFolder to " + ModFolder);
			}
		}

		public void AddSubFolder(string FolderName)
		{
			SubFolders.Add(FolderName);
			if (debug)
			{
				MelonLogger.Msg("Added Subfolder " + FolderName);
			}
		}

		public void RemoveSubFolder(string FolderName)
		{
			SubFolders.Remove(FolderName);
			if (debug)
			{
				MelonLogger.Msg("Removed Subfolder " + FolderName);
			}
		}

		public void CheckAllFoldersExist()
		{
			CreateFolderIfNotExisting(GetFolderString());
			if (SubFolders.Count <= 0)
			{
				return;
			}
			foreach (string subFolder in SubFolders)
			{
				CreateFolderIfNotExisting(GetFolderString(subFolder));
			}
		}

		public void RemoveOtherFolders()
		{
			if (debug)
			{
				MelonLogger.Msg("Folder Removal: Start");
			}
			string[] directories = Directory.GetDirectories(GetFolderString("", IgnoreList: true));
			string[] array = directories;
			foreach (string text in array)
			{
				if (debug)
				{
					MelonLogger.Msg(text);
				}
				string text2 = text.Split(new char[1] { '\\' })[^1];
				if (CheckIfFolderInList(text2))
				{
					Directory.Delete(GetFolderString(text2, IgnoreList: true), recursive: true);
					if (debug)
					{
						MelonLogger.Msg("Deleted: " + GetFolderString(text2, IgnoreList: true));
					}
				}
			}
			if (debug)
			{
				MelonLogger.Msg("Folder Removal: End");
			}
		}

		private string GetFolderString(string SubFolder = "", bool IgnoreList = false)
		{
			string text = UserData + "\\" + ModFolder;
			if (SubFolder != "" && (SubFolders.Contains(SubFolder) || IgnoreList))
			{
				text = ((!IgnoreList) ? (text + "\\" + SubFolders.FirstOrDefault((string x) => x.Contains(SubFolder))) : (text + "\\" + SubFolder));
				if (debug)
				{
					MelonLogger.Msg("Generated Path: " + text);
				}
			}
			else if (debug)
			{
				MelonLogger.Msg("Generated Path with no SubFolder: " + text);
			}
			return text;
		}

		private void CreateFolderIfNotExisting(string Path)
		{
			if (debug && !Directory.Exists(Path))
			{
				MelonLogger.Msg("Path doesn't exist: " + Path);
			}
			else if (debug && Directory.Exists(Path))
			{
				MelonLogger.Msg("Path does exist: " + Path);
			}
			if (!Directory.Exists(Path))
			{
				Directory.CreateDirectory(Path);
			}
		}

		private bool CheckIfFolderInList(string FolderName)
		{
			bool flag = false;
			string folderString = GetFolderString(FolderName, IgnoreList: true);
			if (!SubFolders.Contains(FolderName) && Directory.Exists(folderString))
			{
				flag = true;
			}
			if (debug && flag)
			{
				MelonLogger.Msg("Folder not in List " + folderString);
			}
			else if (debug && !flag)
			{
				MelonLogger.Msg("Folder in List " + folderString);
			}
			return flag;
		}
	}

	internal class Button
	{
		private GameObject ButtonTemplate;

		public List<GameObject> Buttons = new List<GameObject>();

		public void GetTemplateButton()
		{
			if ((Object)(object)ButtonTemplate == (Object)null)
			{
				GameObject val = GameObject.Find("------------TUTORIAL------------/Static tutorials/RUMBLE Starter Guide/Next Page Button/InteractionButton");
				ButtonTemplate = Object.Instantiate<GameObject>(val);
				((UnityEventBase)((Component)ButtonTemplate.transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed).m_PersistentCalls.Clear();
				((Object)ButtonTemplate).name = "ButtonTemplate";
				ButtonTemplate.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)ButtonTemplate);
			}
		}

		public void AddButton(string name)
		{
			GameObject val = Object.Instantiate<GameObject>(ButtonTemplate);
			((Object)val).name = name;
			Buttons.Add(val);
		}

		public void RemoveButton(string name)
		{
			Enumerator<GameObject> enumerator = Buttons.GetEnumerator();
			while (enumerator.MoveNext())
			{
				GameObject current = enumerator.Current;
				if (((Object)current).name == name)
				{
					GameObject val = current;
					Buttons.Remove(val);
					break;
				}
			}
		}

		public UnityEvent OnPressed(string name = "", int index = -1)
		{
			if (name != "")
			{
				int num = SearchButtonList(name);
				if (num != -1)
				{
					return ((Component)Buttons[num].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed;
				}
				return ((Component)Buttons[0].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed;
			}
			if (index != -1)
			{
				return ((Component)Buttons[index].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed;
			}
			return ((Component)Buttons[0].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed;
		}

		private int SearchButtonList(string name)
		{
			for (int i = 0; i < Buttons.Count; i++)
			{
				if (((Object)Buttons[i]).name == name)
				{
					return i;
				}
			}
			return -1;
		}
	}

	internal class StringExtension
	{
		public static string SanitizeName(string Input)
		{
			bool flag = false;
			char[] array = Input.ToCharArray();
			string text = "";
			if (Input.Contains("<u>"))
			{
				Input.Replace("<u>", "");
			}
			if (Input.Contains(","))
			{
				Input.Replace(",", "");
			}
			for (int i = 0; i < Input.Length; i++)
			{
				if (array[i] == '<' && i != Input.Length && (array[i + 1] == '#' || array[i + 1] == 'c'))
				{
					flag = true;
				}
				if (!flag)
				{
					text += array[i];
				}
				if (array[i] == '>')
				{
					flag = false;
				}
			}
			return text;
		}
	}
}
public static class BuildInfo
{
	public const string ModName = "PingDisplay";

	public const string ModVersion = "1.1.2";

	public const string Description = "Gets the Ping of Players";

	public const string Author = "Baumritter";

	public const string Company = "";
}
public class PlayerPing
{
	public string userID = "";

	public string name = "";

	public int ping = 0;
}
public class PingContainer
{
	private PlayerManager pmref = null;

	private PlayerPing hostping = new PlayerPing();

	private List<PlayerPing> playerpings = new List<PlayerPing>();

	public void GetPlayerPings(bool InitList)
	{
		GetHostPing();
		if (InitList)
		{
			ClearPlayerList();
		}
		if (hostping.ping == -1)
		{
			return;
		}
		try
		{
			Enumerator<Player> enumerator = pmref.AllPlayers.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Player current = enumerator.Current;
				PlayerPing playerPing = new PlayerPing();
				if (current.Data.GeneralData.ActorNo != 1)
				{
					playerPing.userID = current.Data.GeneralData.InternalUsername;
					playerPing.name = General.StringExtension.SanitizeName(current.Data.GeneralData.PublicUsername);
					playerPing.ping = GetPingFromString(((Component)current.Controller).gameObject.GetComponent<PhotonView>().Controller.CustomProperties.ToString());
					if (playerPing.ping != -1)
					{
						playerPing.ping += hostping.ping;
					}
					playerpings.Add(playerPing);
				}
			}
		}
		catch
		{
			playerpings.Clear();
		}
	}

	public string ReturnAllPings()
	{
		string text = "Host" + Environment.NewLine + "Ping: " + hostping.ping.ToString().PadRight(4) + " Name: " + hostping.name + Environment.NewLine + "Client" + Environment.NewLine;
		foreach (PlayerPing playerping in playerpings)
		{
			text = text + "Ping: " + playerping.ping.ToString().PadRight(4) + " Name: " + playerping.name + Environment.NewLine;
		}
		return text;
	}

	public PlayerPing ReturnPing(int PlayerNumber)
	{
		if (PlayerNumber == 0)
		{
			return hostping;
		}
		if (playerpings.Count == 0)
		{
			return new PlayerPing
			{
				name = "None",
				userID = "None",
				ping = 0
			};
		}
		return playerpings[PlayerNumber - 1];
	}

	public void DebugLog()
	{
		MelonLogger.Msg("Host - Name: " + hostping.name + " ID: " + hostping.userID + " Ping: " + hostping.ping);
		foreach (PlayerPing playerping in playerpings)
		{
			MelonLogger.Msg("Client - Name: " + playerping.name + " ID: " + playerping.userID + " Ping: " + playerping.ping);
		}
	}

	private void GetHostPing()
	{
		InitPM();
		PlayerPing playerPing = new PlayerPing();
		Enumerator<Player> enumerator = pmref.AllPlayers.GetEnumerator();
		while (enumerator.MoveNext())
		{
			Player current = enumerator.Current;
			if (current.Data.GeneralData.ActorNo == 1 || current.Data.GeneralData.ActorNo == -1)
			{
				playerPing.userID = current.Data.GeneralData.InternalUsername;
				playerPing.name = General.StringExtension.SanitizeName(current.Data.GeneralData.PublicUsername);
				try
				{
					playerPing.ping = GetPingFromString(((Component)current.Controller).gameObject.GetComponent<PhotonView>().Controller.CustomProperties.ToString());
				}
				catch
				{
					playerPing.ping = -1;
				}
				break;
			}
		}
		hostping = playerPing;
	}

	private void ClearPlayerList()
	{
		playerpings.Clear();
	}

	private int GetPingFromString(string str)
	{
		int result = -1;
		string[] array = str.Split(new char[1] { ',' });
		string[] array2 = array;
		foreach (string text in array2)
		{
			if (text.Contains("ping"))
			{
				string text2 = text.Split(new char[1] { ')' })[^1];
				text2.Replace(" ", string.Empty);
				int.TryParse(text2, out result);
				if (!int.TryParse(text2, out var _))
				{
					result = -1;
				}
			}
		}
		return result;
	}

	private void InitPM()
	{
		if ((Object)(object)pmref == (Object)null)
		{
			pmref = GameObject.Find("Game Instance/Initializable/PlayerManager").GetComponent<PlayerManager>();
		}
	}
}
public class PingDisplayClass : MelonMod
{
	private UI UI;

	private Mod Mod = new Mod();

	private General.Delay Delay = new General.Delay();

	private General.Delay MatchInfoDelay = new General.Delay();

	public static PingContainer Pings = new PingContainer();

	private GameObject MatchInfoRef = null;

	private GameObject RemotePlayerText = null;

	private GameObject LocalPlayerText = null;

	private PlayerManager PlayerManager = null;

	private string currentscene;

	private bool MatchInfoRefDone = false;

	private bool MatchInfoRefInvalid = false;

	private string currentuser = "";

	public override void OnLateInitializeMelon()
	{
		((MelonBase)this).OnLateInitializeMelon();
		UI = RumbleModUIClass.UI_Obj;
		Mod.ModName = "PingDisplay";
		Mod.ModVersion = "1.1.2";
		Mod.SetFolder("PingDisplay");
		Mod.AddToList("Description", (AvailableTypes)0, "", "Gets the Ping of Players");
		Mod.AddToList("Pings", (AvailableTypes)0, "", "None.");
		Mod.GetFromFile();
	}

	public override void OnFixedUpdate()
	{
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		((MelonBase)this).OnFixedUpdate();
		if (UI.GetInit() && !Mod.GetUIStatus())
		{
			UI.AddMod(Mod);
			MelonLogger.Msg("Added Mod.");
			Delay.Delay_Start(1.0);
		}
		if (currentscene == "Gym" && (Object)(object)PlayerManager == (Object)null)
		{
			PlayerManager = GameObject.Find("Game Instance/Initializable/PlayerManager").GetComponent<PlayerManager>();
		}
		if (Delay.Done && UI.IsUIVisible() && UI.IsModSelected("PingDisplay") && UI.IsOptionSelected("Pings"))
		{
			Pings.GetPlayerPings(InitList: true);
			Mod.Settings[1].Description = Pings.ReturnAllPings();
			UI.ForceRefresh();
			Delay.Delay_Start(1.0);
		}
		if (MatchInfoDelay.Done && !MatchInfoRefInvalid)
		{
			if ((Object)(object)MatchInfoRef != (Object)null)
			{
				MelonLogger.Msg("Children clone start");
				RemotePlayerText = Object.Instantiate<GameObject>(((Component)MatchInfoRef.transform.GetChild(5)).gameObject);
				LocalPlayerText = Object.Instantiate<GameObject>(((Component)MatchInfoRef.transform.GetChild(6)).gameObject);
				((Object)RemotePlayerText).name = "Remote Ping";
				((Object)LocalPlayerText).name = "Local Ping";
				RemotePlayerText.transform.SetParent(MatchInfoRef.transform, false);
				LocalPlayerText.transform.SetParent(MatchInfoRef.transform, false);
				RemotePlayerText.transform.localPosition = new Vector3(-1.25f, 1.5f, 0f);
				LocalPlayerText.transform.localPosition = new Vector3(1.25f, 1.5f, 0f);
				((TMP_Text)RemotePlayerText.GetComponent<TextMeshPro>()).text = "999ms";
				((TMP_Text)LocalPlayerText.GetComponent<TextMeshPro>()).text = "999ms";
				MatchInfoDelay.Done = false;
				MatchInfoRefDone = true;
				MelonLogger.Msg("Children cloned");
			}
			else
			{
				MatchInfoRef = GameObject.Find("MatchInfoMod");
				if ((Object)(object)MatchInfoRef == (Object)null)
				{
					MatchInfoRefInvalid = true;
					MelonLogger.Msg("MatchInfoRef doesn't exist");
				}
				else
				{
					MelonLogger.Msg("MatchInfoRef get");
				}
			}
		}
		if (Delay.Done && (currentscene == "Map0" || currentscene == "Map1") && MatchInfoRefDone && !MatchInfoRefInvalid)
		{
			Pings.GetPlayerPings(InitList: true);
			if (PhotonNetwork.IsMasterClient)
			{
				((TMP_Text)RemotePlayerText.GetComponent<TextMeshPro>()).text = Pings.ReturnPing(1).ping + "ms";
				((TMP_Text)LocalPlayerText.GetComponent<TextMeshPro>()).text = Pings.ReturnPing(0).ping + "ms";
			}
			else
			{
				((TMP_Text)RemotePlayerText.GetComponent<TextMeshPro>()).text = Pings.ReturnPing(0).ping + "ms";
				((TMP_Text)LocalPlayerText.GetComponent<TextMeshPro>()).text = Pings.ReturnPing(1).ping + "ms";
			}
			Delay.Delay_Start(1.0);
		}
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName);
		currentscene = sceneName;
		if ((currentscene == "Map0" || currentscene == "Map1") && (Object)(object)MatchInfoRef == (Object)null)
		{
			MatchInfoDelay.Delay_Start(0.5, AllowRetrigger: true);
		}
	}
}