RUMBLE does not support other mod managers. If you want to use a manager, you must use the RUMBLE Mod Manager, a manager specifically designed for this game.
Decompiled source of BPTracker v2.0.1
Mods/BPTracker.dll
Decompiled a year agousing 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 Il2CppRUMBLE.Interactions.InteractionBase; using Il2CppRUMBLE.Social.Phone; using Il2CppSystem; using MelonLoader; 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", "2.0.1", "Baumritter", null)] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: VerifyLoaderVersion(0, 6, 4, true)] [assembly: MelonColor(200, 0, 200, 0)] [assembly: MelonAuthorColor(200, 0, 200, 0)] [assembly: AssemblyTitle("BPTracker")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BPTracker")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("caa17032-5000-4195-b343-c26492084360")] [assembly: AssemblyFileVersion("2.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.0.1.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 static class BuildInfo { public const string ModName = "BPTracker"; public const string ModVersion = "2.0.1"; public const string Description = "Tracks BP"; public const string Author = "Baumritter"; public const string Company = ""; } 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 = ((object)(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); } } }