Decompiled source of BPTracker v1.2.1

Mods/BPTracker.dll

Decompiled 3 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 BPTracker;
using Il2CppSystem;
using MelonLoader;
using RUMBLE.Interactions.InteractionBase;
using RUMBLE.Social.Phone;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(BPTrackerClass), "BPTracker", "1.2.1", "Baumritter", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: AssemblyTitle("BPTracker")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BPTracker")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7563b7ca-ebe1-428e-8669-99f62cbf56ab")]
[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 BPTracker;

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 = false;

	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;
	}
}
public class PlayerInfo
{
	private readonly string listseparator = ",";

	public string Username { get; set; }

	public string BattlePoints { get; set; }

	public string Platform { get; set; }

	public string UserID { get; set; }

	public string BPChangeTime { get; set; }

	public string ReturnFileString()
	{
		return BattlePoints + listseparator + Username + listseparator + Platform + listseparator + UserID + listseparator + BPChangeTime + Environment.NewLine;
	}

	public void 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;
			}
		}
		Username = text;
	}
}
public class BPTrackerClass : MelonMod
{
	private const double SceneDelay = 5.0;

	private const double RecentDelay = 5.0;

	private const string LogFilePath = "UserData\\BPTracker\\Logs\\BPList.csv";

	private const string FriendList = "/Telephone 2.0 REDUX special edition/Friend Screen/Player Tags/";

	private const string PageDown = "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/PageDownButton/Button";

	private const string PageUp = "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/PageUpButton/Button";

	private const string ScrollDown = "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/ScrollDownButton/Button";

	private const string ScrollUp = "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/ScrollUpButton/Button";

	private const string RecentList = "/Telephone 2.0 REDUX special edition/Recent Screen/Player Tags/";

	private const string SlidingObject = "/Telephone 2.0 REDUX special edition/Recent Screen";

	private const string ParkPrefix = "________________LOGIC__________________ /Heinhouwser products";

	private const string GymPrefix = "--------------LOGIC--------------/Heinhouser products";

	private const string Leaderboard = "--------------LOGIC--------------/Heinhouser products/Leaderboard/Player Tags/";

	private readonly bool debug = false;

	private bool friendlistbuttonstate = false;

	private bool friendlistbuttonwait = false;

	private bool scenechanged = false;

	private bool recentleverlockout = false;

	private bool prefixlockout = false;

	private bool logfileerror = false;

	private string currentScene = "";

	private string objprefix = "";

	private PlayerInfo InfoObj;

	private PlayerTag playertag;

	private PhonePage phonepage;

	private InteractionButton b1;

	private InteractionButton b2;

	private InteractionButton b3;

	private InteractionButton b4;

	private Delay Delay_SceneLoad = new Delay
	{
		name = "LoadDelay"
	};

	private Delay Delay_RecentBoard = new Delay
	{
		name = "RecentDelay"
	};

	private Folders folders = new Folders();

	private string[] Tags = new string[6];

	private string[] Tags2 = new string[6];

	public override void OnLateInitializeMelon()
	{
		((MelonBase)this).OnLateInitializeMelon();
		folders.SetModFolderNamespace();
		folders.AddSubFolder("Logs");
		folders.CheckAllFoldersExist();
		Tags[0] = "Player Tag 2.0";
		Tags[1] = "Player Tag 2.0 (1)";
		Tags[2] = "Player Tag 2.0 (2)";
		Tags[3] = "Player Tag 2.0 (3)";
		Tags[4] = "Player Tag 2.0 (4)";
		Tags[5] = "Player Tag 2.0 (5)";
		Tags2[0] = "HighscoreTag/";
		Tags2[1] = "HighscoreTag (1)/";
		Tags2[2] = "HighscoreTag (2)/";
		Tags2[3] = "HighscoreTag (3)/";
		Tags2[4] = "HighscoreTag (4)/";
		Tags2[5] = "PersonalHighscoreTag/";
	}

	public override void OnUpdate()
	{
		((MelonBase)this).OnUpdate();
		if (logfileerror)
		{
			return;
		}
		SwapPrefix();
		try
		{
			if (!(currentScene == "Gym") && !(currentScene == "Park"))
			{
				return;
			}
			GetFriendListButtonStatus();
			GetRecentPageStatus();
			if (!(friendlistbuttonstate | scenechanged | Delay_RecentBoard.Done) || !Delay_SceneLoad.Done)
			{
				return;
			}
			if (scenechanged && currentScene == "Gym")
			{
				for (int i = 0; i < Tags.Length; i++)
				{
					InfoObj = GetFromBoardList("--------------LOGIC--------------/Heinhouser products/Leaderboard/Player Tags/" + Tags2[i] + Tags[0]);
					if (InfoObj != null)
					{
						SearchandReplaceInFile(InfoObj);
						if (logfileerror)
						{
							return;
						}
					}
				}
				scenechanged = false;
				if (debug)
				{
					MelonLogger.Msg("Leaderboard Checked.");
				}
			}
			if (friendlistbuttonstate)
			{
				for (int j = 0; j < Tags.Length; j++)
				{
					InfoObj = GetFromBoardList(objprefix + "/Telephone 2.0 REDUX special edition/Friend Screen/Player Tags/" + Tags[j]);
					if (InfoObj != null)
					{
						SearchandReplaceInFile(InfoObj);
						if (logfileerror)
						{
							return;
						}
					}
				}
				friendlistbuttonstate = false;
				if (debug)
				{
					MelonLogger.Msg("Friend Board Checked.");
				}
			}
			if (Delay_RecentBoard.Done)
			{
				for (int k = 0; k < Tags.Length; k++)
				{
					InfoObj = GetFromBoardList(objprefix + "/Telephone 2.0 REDUX special edition/Recent Screen/Player Tags/" + Tags[k]);
					if (InfoObj != null)
					{
						SearchandReplaceInFile(InfoObj);
						if (logfileerror)
						{
							return;
						}
					}
				}
				Delay_RecentBoard.Done = false;
				if (debug)
				{
					MelonLogger.Msg("Recent Board Checked");
				}
			}
			if (debug)
			{
				MelonLogger.Msg("Something evaluated.");
			}
		}
		catch
		{
			if ((friendlistbuttonstate | scenechanged | Delay_RecentBoard.Done) && Delay_SceneLoad.Done && debug)
			{
				MelonLogger.Msg("Try Failed.");
			}
		}
	}

	public PlayerInfo GetFromBoardList(string TagString)
	{
		PlayerInfo playerInfo = new PlayerInfo();
		playertag = GameObject.Find(TagString).GetComponent<PlayerTag>();
		if (playertag.UserData != null && ((Behaviour)playertag).isActiveAndEnabled)
		{
			playerInfo.SanitizeName(playertag.UserData.publicName);
			playerInfo.BattlePoints = playertag.UserData.battlePoints.ToString();
			playerInfo.UserID = playertag.UserData.playFabId.ToString();
			switch (playertag.UserData.platformId)
			{
			case 'O':
				playerInfo.Platform = "Oculus";
				break;
			case 'S':
				playerInfo.Platform = "Steam";
				break;
			default:
				playerInfo.Platform = "Unknown";
				break;
			}
		}
		else
		{
			playerInfo = null;
		}
		return playerInfo;
	}

	public void GetFriendListButtonStatus()
	{
		b1 = GameObject.Find(objprefix + "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/ScrollUpButton/Button").GetComponent<InteractionButton>();
		b2 = GameObject.Find(objprefix + "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/ScrollDownButton/Button").GetComponent<InteractionButton>();
		b3 = GameObject.Find(objprefix + "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/PageUpButton/Button").GetComponent<InteractionButton>();
		b4 = GameObject.Find(objprefix + "/Telephone 2.0 REDUX special edition/Friend Screen/Friend Scroll Bar/PageDownButton/Button").GetComponent<InteractionButton>();
		if (!b1.isPressed && !b2.isPressed && !b3.isPressed && !b4.isPressed && !friendlistbuttonwait)
		{
			friendlistbuttonwait = true;
			if (debug)
			{
				MelonLogger.Msg("No Button pressed.");
			}
		}
		if ((b1.isPressed || b2.isPressed || b3.isPressed || b4.isPressed) && !friendlistbuttonstate && friendlistbuttonwait)
		{
			friendlistbuttonwait = false;
			friendlistbuttonstate = true;
			if (debug)
			{
				MelonLogger.Msg("Button pressed.");
			}
		}
	}

	public void GetRecentPageStatus()
	{
		phonepage = GameObject.Find(objprefix + "/Telephone 2.0 REDUX special edition/Recent Screen").GetComponent<PhonePage>();
		if (!phonepage.pagePositionIsUpdating && !phonepage.pageActivated && recentleverlockout)
		{
			Delay_RecentBoard.Done = false;
			recentleverlockout = false;
		}
		if (!phonepage.pagePositionIsUpdating && phonepage.pageActivated && !Delay_RecentBoard.Done && !recentleverlockout)
		{
			Delay_RecentBoard.Delay_Start(5.0);
			recentleverlockout = true;
		}
	}

	public void SwapPrefix()
	{
		if (!scenechanged || prefixlockout)
		{
			return;
		}
		string text = currentScene;
		string text2 = text;
		if (!(text2 == "Gym"))
		{
			if (text2 == "Park")
			{
				objprefix = "________________LOGIC__________________ /Heinhouwser products";
				prefixlockout = true;
				scenechanged = false;
				if (debug)
				{
					MelonLogger.Msg("Prefix changed to Park.");
				}
			}
		}
		else
		{
			objprefix = "--------------LOGIC--------------/Heinhouser products";
			prefixlockout = true;
			if (debug)
			{
				MelonLogger.Msg("Prefix changed to Gym.");
			}
		}
	}

	public void SearchandReplaceInFile(PlayerInfo Input)
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		int num = -1;
		int num2 = 0;
		if (File.Exists("UserData\\BPTracker\\Logs\\BPList.csv"))
		{
			string[] array;
			try
			{
				array = File.ReadAllLines("UserData\\BPTracker\\Logs\\BPList.csv");
			}
			catch
			{
				MelonLogger.Msg("CLOSE THE LOG FILE. EXECUTION SUSPENDED UNTIL NEXT SCENE CHANGE.");
				logfileerror = true;
				return;
			}
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (text.Contains(Input.UserID))
				{
					num = num2;
					break;
				}
				num2++;
			}
			if (num != -1)
			{
				if (!array[num].Contains(Input.BattlePoints))
				{
					DateTime now = DateTime.Now;
					Input.BPChangeTime = ((DateTime)(ref now)).ToString();
					array[num] = Input.ReturnFileString();
					File.WriteAllLines("UserData\\BPTracker\\Logs\\BPList.csv", array);
					if (debug)
					{
						MelonLogger.Msg("Changed: " + Input.UserID + " " + Input.Username + " " + Input.BattlePoints + " in Line: " + num);
					}
				}
				else if (debug)
				{
					MelonLogger.Msg("Changed Nothing in Line " + num);
				}
			}
			else
			{
				Input.BPChangeTime = "New Entry";
				File.AppendAllText("UserData\\BPTracker\\Logs\\BPList.csv", Input.ReturnFileString());
				if (debug)
				{
					MelonLogger.Msg("Appended: " + Input.UserID + " " + Input.Username + " " + Input.BattlePoints);
				}
			}
			RemoveEmptyLinesFromFile();
		}
		else
		{
			Input.BPChangeTime = "New Entry";
			File.AppendAllText("UserData\\BPTracker\\Logs\\BPList.csv", "BP,Name,Platform,UserID,LastChange" + Environment.NewLine);
			File.AppendAllText("UserData\\BPTracker\\Logs\\BPList.csv", Input.ReturnFileString());
			if (debug)
			{
				MelonLogger.Msg("NF Appended: " + Input.UserID + " " + Input.Username + " " + Input.BattlePoints);
			}
		}
	}

	private void RemoveEmptyLinesFromFile()
	{
		File.WriteAllLines("UserData\\BPTracker\\Logs\\BPList.csv", from l in File.ReadAllLines("UserData\\BPTracker\\Logs\\BPList.csv")
			where !string.IsNullOrWhiteSpace(l)
			select l);
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName);
		currentScene = sceneName;
		scenechanged = true;
		prefixlockout = false;
		logfileerror = false;
		Delay_SceneLoad.Delay_Start(5.0);
		if (debug)
		{
			MelonLogger.Msg("Scene changed to " + currentScene.ToString() + " = " + scenechanged);
		}
	}
}