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 RankedRumble v1.0.1
Mods/RankedRumble.dll
Decompiled 2 months agousing System; using System.Collections; using System.Diagnostics; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Il2CppExitGames.Client.Photon; using Il2CppPhoton.Pun; using Il2CppPhoton.Realtime; using Il2CppRUMBLE.Managers; using Il2CppRUMBLE.Utilities; using Il2CppSystem; using Il2CppTMPro; using MelonLoader; using Microsoft.CodeAnalysis; using RankedRumble; using RumbleModUI; using RumbleModdingAPI; 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(Main), "RankedRumble", "1.0.1", "PeppaStone", null)] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: MelonColor(255, 255, 51, 238)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("RankedRumble")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RankedRumble")] [assembly: AssemblyTitle("RankedRumble")] [assembly: AssemblyVersion("1.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; } } } namespace RankedRumble { public static class BuildInfo { public const string ModName = "RankedRumble"; public const string ModVersion = "1.0.1"; public const string Description = "Have an ELO on rumble"; public const string Author = "PeppaStone"; public const string Company = "PeppaStone"; } public class Main : MelonMod { public class PlayerData { public string id; public string name; } private static readonly HttpClient client = new HttpClient(); private const string ApiUrl = "http://18.219.214.193:80/"; private bool init = false; private string currentMap = ""; public static Mod Mod = new Mod(); private ModSetting<bool> isRanked; private bool isRankedMatch = false; private int localRounds = 0; private int remoteRounds = 0; private GameObject rankedTextObject; private bool areELOsReady = false; private string localELO = ""; private string remoteELO = ""; private TextMeshPro localELOTextComponent; private TextMeshPro remoteELOTextComponent; private GameObject isRankedText; private GameObject isRankedButton; public override void OnLateInitializeMelon() { Calls.onMapInitialized += MapLoaded; UI.instance.UI_Initialized += OnUIInit; Calls.onRoundEnded += OnRoundEnded; Calls.onMatchEnded += OnMatchEnded; } [Obsolete] public void OnUIInit() { Mod.ModName = "RankedRumble"; Mod.ModVersion = "1.0.1"; Mod.SetFolder("RankedRumble"); Mod.AddDescription("Description", "", "Have an ELO on rumble", true, false); isRanked = Mod.AddToList("Ranked", true, 0, "Will your next game be ranked?"); Mod.GetFromFile(); Mod.SaveModData("RankedRumble"); UI.instance.AddMod(Mod); } public void OnEvent(EventData eventData) { if ((!(currentMap != "Map0") || !(currentMap != "Map1")) && eventData.Code == 61 && (bool)((ModSetting)isRanked).Value) { MelonLogger.Msg("Ranked Match Confirmed"); FetchPlayersEloAsync(Singleton<PlayerManager>.Instance.AllPlayers[0].Data.GeneralData.PlayFabMasterId, Singleton<PlayerManager>.Instance.AllPlayers[1].Data.GeneralData.PlayFabMasterId); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { localRounds = 0; remoteRounds = 0; isRankedMatch = false; areELOsReady = false; currentMap = sceneName; } public void MapLoaded() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown if (currentMap == "Loader") { return; } Init(); if (currentMap == "Gym") { if ((bool)((ModSetting)isRanked).Value) { isRankedText = Create.NewText("Current: Ranked", 0.8f, Color.blue, new Vector3(4.0309f, 1.2964f, 8.84f), Quaternion.Euler(0f, 40f, 0f)); isRankedButton = Create.NewButton(new Vector3(4.0309f, 1.2964f, 8.84f), Quaternion.Euler(90f, 220.1446f, 0f), (Action)SwitchRankedCasual); } else { isRankedText = Create.NewText("Current: Casual", 0.8f, Color.white, new Vector3(4.0309f, 1.2964f, 8.84f), Quaternion.Euler(0f, 40f, 0f)); isRankedButton = Create.NewButton(new Vector3(4.0309f, 1.2964f, 8.84f), Quaternion.Euler(90f, 220.1446f, 0f), (Action)SwitchRankedCasual); } isRankedText.transform.position = new Vector3(4.0309f, 1.1637f, 8.84f); isRankedText.transform.rotation = Quaternion.Euler(0f, 40f, 0f); ((Object)isRankedText).name = "RankedText"; ((Object)isRankedButton).name = "RankedButton"; } if ((currentMap == "Map0" || currentMap == "Map1") && (bool)((ModSetting)isRanked).Value) { PhotonNetwork.RaiseEvent((byte)61, Object.op_Implicit("away"), new RaiseEventOptions { Receivers = (ReceiverGroup)0 }, SendOptions.SendReliable); } } public void SwitchRankedCasual() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) ((ModSetting)isRanked).Value = !(bool)((ModSetting)isRanked).Value; if ((bool)((ModSetting)isRanked).Value) { ((TMP_Text)isRankedText.GetComponent<TextMeshPro>()).text = "Current: Ranked"; ((Graphic)isRankedText.GetComponent<TextMeshPro>()).color = Color.blue; } else { ((TMP_Text)isRankedText.GetComponent<TextMeshPro>()).text = "Current: Casual"; ((Graphic)isRankedText.GetComponent<TextMeshPro>()).color = Color.white; } ((ModSetting)isRanked).SavedValue = (bool)((ModSetting)isRanked).Value; } public override void OnUpdate() { if (areELOsReady) { MelonCoroutines.Start(MakeAndRemoveELOText()); areELOsReady = false; } } public IEnumerator MakeAndRemoveELOText() { MakeELOText(); yield return (object)new WaitForSeconds(5f); Object.Destroy((Object)(object)rankedTextObject); } public async void TestElo() { HttpResponseMessage response1 = await client.GetAsync("http://18.219.214.193:80/player/" + Singleton<PlayerManager>.Instance.localPlayer.Data.GeneralData.PlayFabMasterId); response1.EnsureSuccessStatusCode(); MelonLogger.Msg(await response1.Content.ReadAsStringAsync()); } public async Task FetchPlayersEloAsync(string player1Id, string player2Id) { try { MelonLogger.Msg("Attemtping to get ELOs"); HttpResponseMessage response1 = await client.GetAsync("http://18.219.214.193:80/player/" + player1Id); response1.EnsureSuccessStatusCode(); string elo1 = await response1.Content.ReadAsStringAsync(); HttpResponseMessage response2 = await client.GetAsync("http://18.219.214.193:80/player/" + player2Id); response2.EnsureSuccessStatusCode(); string elo2 = await response2.Content.ReadAsStringAsync(); MelonLogger.Msg("ELOs gotten succesfully. " + elo1 + " " + elo2); localELO = elo1; remoteELO = elo2; areELOsReady = true; isRankedMatch = true; } catch (Exception ex2) { Exception ex = ex2; MelonLogger.Error($"Error fetching player ELOs: {ex}"); } } public void Init() { if (!init) { CreatePlayerOnServer(); init = true; } } public void MakeELOText() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) rankedTextObject = Create.NewText("RANKED MATCH", 2f, Color.red, Vector3.zero, Quaternion.identity); rankedTextObject.transform.localPosition = new Vector3(0f, 3f, 0f); rankedTextObject.transform.localRotation = (PhotonNetwork.IsMasterClient ? Quaternion.Euler(0f, 180f, 0f) : Quaternion.Euler(0f, 0f, 0f)); TextMeshPro component = rankedTextObject.GetComponent<TextMeshPro>(); ((TMP_Text)component).alignment = (TextAlignmentOptions)514; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).outlineWidth = 0.2f; GameObject val = Create.NewText(Singleton<PlayerManager>.Instance.AllPlayers[0].Data.GeneralData.PublicUsername + ": " + localELO, 1f, Color.white, Vector3.zero, Quaternion.identity); val.transform.parent = rankedTextObject.transform; val.transform.localPosition = new Vector3(0f, -0.25f, 0f); val.transform.localRotation = Quaternion.identity; localELOTextComponent = val.GetComponent<TextMeshPro>(); ((TMP_Text)localELOTextComponent).alignment = (TextAlignmentOptions)514; ((TMP_Text)localELOTextComponent).enableWordWrapping = false; ((TMP_Text)localELOTextComponent).outlineWidth = 0.1f; GameObject val2 = Create.NewText(Singleton<PlayerManager>.Instance.AllPlayers[1].Data.GeneralData.PublicUsername + ": " + remoteELO, 1f, Color.white, Vector3.zero, Quaternion.identity); val2.transform.parent = rankedTextObject.transform; val2.transform.localPosition = new Vector3(0f, -0.5f, 0f); val2.transform.localRotation = Quaternion.identity; remoteELOTextComponent = val2.GetComponent<TextMeshPro>(); ((TMP_Text)remoteELOTextComponent).alignment = (TextAlignmentOptions)514; ((TMP_Text)remoteELOTextComponent).enableWordWrapping = false; ((TMP_Text)remoteELOTextComponent).outlineWidth = 0.1f; } public void OnRoundEnded() { try { if (Singleton<PlayerManager>.Instance.AllPlayers[0].Data == null || Singleton<PlayerManager>.Instance.AllPlayers[1].Data == null) { MelonLogger.Warning("[WARNING] Missing local player data. Skipping round tracking."); return; } if (Singleton<PlayerManager>.Instance.AllPlayers[0].Data.HealthPoints > 0) { localRounds++; } else { remoteRounds++; } MelonLogger.Msg($"[DEBUG] Round ended. LocalRounds: {localRounds}, RemoteRounds: {remoteRounds}"); } catch (Exception ex) { MelonLogger.Error("[ERROR] Exception in OnRoundEnded: " + ex); } } public void OnMatchEnded() { if (PhotonNetwork.IsMasterClient && isRankedMatch) { SendGameResults(); } } private async void CreatePlayerOnServer() { LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient; networkingClient.EventReceived += Action<EventData>.op_Implicit((Action<EventData>)OnEvent); string playerName = RemoveTags(Singleton<PlayerManager>.Instance.localPlayer.Data.GeneralData.PublicUsername); string playerID = Singleton<PlayerManager>.Instance.localPlayer.Data.GeneralData.PlayFabMasterId; string jsonData = $"{{\"id\": \"{playerID}\", \"name\": \"{playerName}\"}}"; StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json"); try { MelonLogger.Msg("Server Response: " + await (await client.PostAsync("http://18.219.214.193:80/create-player", content)).Content.ReadAsStringAsync()); } catch (HttpRequestException ex) { HttpRequestException e = ex; MelonLogger.Error("Error calling API: " + e.Message); } } private async void SendGameResults() { LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient; networkingClient.EventReceived += Action<EventData>.op_Implicit((Action<EventData>)OnEvent); string hostID = Singleton<PlayerManager>.Instance.AllPlayers[0].Data.GeneralData.PlayFabMasterId; string clientID = Singleton<PlayerManager>.Instance.AllPlayers[1].Data.GeneralData.PlayFabMasterId; int localPing = GetPingFromString(((Object)((Component)Singleton<PlayerManager>.Instance.AllPlayers[0].Controller).gameObject.GetComponent<PhotonView>().Controller.CustomProperties).ToString()); int remotePing = GetPingFromString(((Object)((Component)Singleton<PlayerManager>.Instance.AllPlayers[1].Controller).gameObject.GetComponent<PhotonView>().Controller.CustomProperties).ToString()); int hostScore = localRounds; int clientScore = remoteRounds; string jsonData = $"{{\"hostid\": \"{hostID}\", \"clientid\": \"{clientID}\", \"clientping\": \"{localPing + remotePing}\", \"hostscore\": \"{hostScore}\", \"clientscore\": \"{clientScore}\"}}"; StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json"); try { await (await client.PostAsync("http://18.219.214.193:80/game-results", content)).Content.ReadAsStringAsync(); } catch (HttpRequestException ex) { HttpRequestException e = ex; MelonLogger.Error("Error calling API: " + e.Message); } } public static string RemoveTags(string input) { string pattern = "<#.*?>"; return Regex.Replace(input, pattern, string.Empty); } private int GetPingFromString(string str) { int result = -1; string[] array = str.Split(','); string[] array2 = array; foreach (string text in array2) { if (text.Contains("ping")) { string text2 = text.Split(')')[^1]; text2.Replace(" ", string.Empty); int.TryParse(text2, out result); if (!int.TryParse(text2, out var _)) { result = -1; } } } return result; } } }