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);
}
}
}