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 AutomaticRematch v1.5.0
Mods/AutomaticRematch.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using AutomaticRematch; using HarmonyLib; using Il2CppRUMBLE.Interactions.InteractionBase; using Il2CppRUMBLE.Managers; using Il2CppRUMBLE.Networking.MatchFlow; using Il2CppRUMBLE.Players.Subsystems; using Il2CppRUMBLE.Utilities; using MelonLoader; using MelonLoader.Preferences; using RumbleModdingAPI.RMAPI; using UIFramework; 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(Main), "AutomaticRematch", "1.5.0", "UlvakSkillz", null)] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: MelonColor(255, 195, 0, 255)] [assembly: MelonAuthorColor(255, 195, 0, 255)] [assembly: VerifyLoaderVersion(0, 7, 2, true)] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("AutomaticRematch")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+375dd4674099f3e5f9cb5fca3582e93d5533c6d0")] [assembly: AssemblyProduct("AutomaticRematch")] [assembly: AssemblyTitle("AutomaticRematch")] [assembly: AssemblyVersion("1.0.0.0")] namespace AutomaticRematch; public enum RematchFunction { None, Rematch, Requeue, Exit } public class Main : MelonMod { public static class BuildInfo { public const string ModName = "AutomaticRematch"; public const string ModVersion = "1.5.0"; public const string Description = "Automatically Presses Rematch Button if On"; public const string Author = "UlvakSkillz"; public const string Company = ""; } [HarmonyPatch(typeof(PlayerBoxInteractionSystem), "ExecuteFistBumpReward", new Type[] { typeof(Vector3) })] public static class executeFistBumpReward { private static void Postfix(ref PlayerBoxInteractionSystem __instance, ref Vector3 interactionPosition) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) __instance = ((Component)Singleton<PlayerManager>.instance.localPlayer.Controller).gameObject.GetComponent<PlayerBoxInteractionSystem>(); if (Preferences.PrefRematchType.Value != RematchTypes.RematchOnFistbump) { return; } float num = Vector3.Distance(interactionPosition, (Preferences.PrefPrimaryHand.Value == Hand.Right) ? ((Component)__instance.rightHandTrigger).transform.position : ((Component)__instance.leftHandTrigger).transform.position); float num2 = Vector3.Distance(interactionPosition, (Preferences.PrefPrimaryHand.Value != Hand.Right) ? ((Component)__instance.rightHandTrigger).transform.position : ((Component)__instance.leftHandTrigger).transform.position); if (!inMatch) { if (Math.Abs(num - num2) < 0.01f) { Log("Distance Between Hands too close to same distance, skipping"); } else if (num < num2) { Log("Rematch on Fistbump Rematching"); ((InteractionButton)GetRematchButton().GetComponent<RematchButton>()).RPC_OnToggleStateChanged(true); } else { if (Preferences.PrefSecondaryHandFunction.Value == Function.None) { return; } watchingPlayerCount = false; if (Preferences.PrefSecondaryHandFunction.Value == Function.Requeue) { Log("Rematch on Fistbump secondaryHandFunction Requeueing"); UnityEvent onPressed = ((InteractionButton)((Component)GetRequeueButton().transform.GetChild(1).GetChild(0)).GetComponent<RematchButton>()).OnPressed; try { onPressed.Invoke(); } catch (Exception ex) { Log("MatchEnded Requeue Error OnPressed.Invoke"); Error(ex.InnerException); } GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer); } else if (Preferences.PrefSecondaryHandFunction.Value == Function.Exit) { Log("Rematch on Fistbump secondaryHandFunction Quiting"); UnityEvent onPressed2 = ((Component)GetExitButton().transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>().OnPressed; try { onPressed2.Invoke(); } catch (Exception ex2) { Log("MatchEnded Exit Error OnPressed.Invoke"); Error(ex2.InnerException); } GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer); } } return; } Log("Fistbump Happened, Waiting for Sign"); needsToRunFunction = true; if (num < num2) { rematchFunctionToRun = RematchFunction.None; } else if (Preferences.PrefSecondaryHandFunction.Value != 0) { if (Preferences.PrefSecondaryHandFunction.Value == Function.Requeue) { rematchFunctionToRun = RematchFunction.Requeue; } else { rematchFunctionToRun = RematchFunction.Exit; } } } } [CompilerGenerated] private sealed class <MatchEndedAutoPress>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Main <>4__this; private float <buttonValue>5__1; private ControllerButtons <>s__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MatchEndedAutoPress>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(Preferences.PrefTimeBeforeRematch.Value); <>1__state = 1; return true; case 1: { <>1__state = -1; <buttonValue>5__1 = 0f; ControllerButtons value = Preferences.PrefPreventAutoRematchButton.Value; <>s__2 = value; switch (<>s__2) { case ControllerButtons.LeftControllerTrigger: <buttonValue>5__1 = LeftController.GetTrigger(); break; case ControllerButtons.LeftControllerPrimary: <buttonValue>5__1 = LeftController.GetPrimary(); break; case ControllerButtons.LeftControllerSecondary: <buttonValue>5__1 = LeftController.GetSecondary(); break; case ControllerButtons.RightControllerTrigger: <buttonValue>5__1 = RightController.GetTrigger(); break; case ControllerButtons.RightControllerPrimary: <buttonValue>5__1 = RightController.GetPrimary(); break; case ControllerButtons.RightControllerSecondary: <buttonValue>5__1 = RightController.GetSecondary(); break; } if (!Preferences.PrefPreventAutoRematchButtonEnabled.Value || <buttonValue>5__1 < 0.5f) { ((InteractionButton)GetRematchButton().GetComponent<RematchButton>()).RPC_OnToggleStateChanged(true); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WatchPlayerCount>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Main <>4__this; private OnePlayerFunction <>s__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WatchPlayerCount>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; Log("WatchPlayerCount Start"); watchingPlayerCount = true; Log("Adding Watchers"); ((Component)GetExitButton().transform.FindChild("InteractionButton/Button")).GetComponent<InteractionButton>().OnPressed.AddListener(UnityAction.op_Implicit((Action)delegate { <>4__this.LeavingMatch(); })); Log("Watcher Exit Button Added"); ((Component)GetRequeueButton().transform.FindChild("InteractionButton/Button")).GetComponent<InteractionButton>().OnPressed.AddListener(UnityAction.op_Implicit((Action)delegate { <>4__this.LeavingMatch(); })); Log("Watcher Requeue Button Added"); break; case 1: <>1__state = -1; break; } if (watchingPlayerCount && Singleton<PlayerManager>.instance.AllPlayers.Count > 1) { <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 1; return true; } Log($"WatchPlayerCount -WHILE LOOP- Done. watchingPlayerCount: {watchingPlayerCount} | PlayerCount: {Singleton<PlayerManager>.instance.AllPlayers.Count}"); if (watchingPlayerCount) { OnePlayerFunction value = Preferences.PrefOnePlayerRemain.Value; <>s__1 = value; switch (<>s__1) { case OnePlayerFunction.SecondaryHandFunction: if (Preferences.PrefOnePlayerRemain.Value == OnePlayerFunction.SecondaryHandFunction) { Log("onePlayerRemainFunction - Secondary Hand Function Requeueing"); GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer); } else if (Preferences.PrefOnePlayerRemain.Value == OnePlayerFunction.Exit) { Log("onePlayerRemainFunction - Secondary Hand Function Exiting"); GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer); } break; case OnePlayerFunction.Requeue: Log("onePlayerRemainFunction - Requeueing"); GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer); break; case OnePlayerFunction.Exit: Log("onePlayerRemainFunction - Exiting"); GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer); break; } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static string currentScene = "Loader"; private static bool needsToRunFunction = false; private static bool inMatch = false; private static bool watchingPlayerCount = false; private static RematchFunction rematchFunctionToRun; private static void Log(string msg) { if (Preferences.PrefDebugging.Value) { Melon<Main>.Logger.Msg(msg); } } private static void Error(Exception msg) { if (Preferences.PrefDebugging.Value) { Melon<Main>.Logger.Error((object)msg); } } public override void OnInitializeMelon() { Preferences.InitPrefs(); UI.Register((MelonMod)(object)this, (MelonPreferences_Category[])(object)new MelonPreferences_Category[3] { Preferences.AutomaticRematchCategory, Preferences.AutoPressSettingsCategory, Preferences.FistbumpSettingsCategory }); } public override void OnLateInitializeMelon() { Actions.onMatchEnded += MatchEnded; Actions.onMatchStarted += matchStarted; } private void matchStarted() { inMatch = true; } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { currentScene = sceneName; inMatch = false; watchingPlayerCount = false; } private void MatchEnded() { Log("MatchEnded()"); inMatch = false; if (Preferences.PrefRematchType.Value == RematchTypes.AutoRematch) { Log("PrefRematchType is RematchTypes.AutoRematch"); MelonCoroutines.Start(MatchEndedAutoPress()); } if (Preferences.PrefRematchType.Value == RematchTypes.RematchOnFistbump && needsToRunFunction) { Log("Running Function from Fistbump Prior"); switch (rematchFunctionToRun) { case RematchFunction.Rematch: Log("Running Function Rematch"); ((InteractionButton)GetRematchButton().GetComponent<RematchButton>()).RPC_OnToggleStateChanged(true); break; case RematchFunction.Requeue: { Log("Running Function Requeue"); UnityEvent onPressed2 = ((InteractionButton)((Component)GetRequeueButton().transform.GetChild(1).GetChild(0)).GetComponent<RematchButton>()).OnPressed; try { onPressed2.Invoke(); } catch (Exception ex2) { Log("MatchEnded Requeue Error OnPressed.Invoke"); Error(ex2.InnerException); } GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer); break; } case RematchFunction.Exit: { Log("Running Function Exit"); UnityEvent onPressed = ((Component)GetExitButton().transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>().OnPressed; try { onPressed.Invoke(); } catch (Exception ex) { Log("MatchEnded Exit Error OnPressed.Invoke"); Error(ex.InnerException); } GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer); needsToRunFunction = false; rematchFunctionToRun = RematchFunction.None; return; } } needsToRunFunction = false; rematchFunctionToRun = RematchFunction.None; } MelonCoroutines.Start(WatchPlayerCount()); } [IteratorStateMachine(typeof(<WatchPlayerCount>d__13))] private IEnumerator WatchPlayerCount() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WatchPlayerCount>d__13(0) { <>4__this = this }; } private void LeavingMatch() { Log("LeavingMatch()"); watchingPlayerCount = false; } [IteratorStateMachine(typeof(<MatchEndedAutoPress>d__15))] private IEnumerator MatchEndedAutoPress() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MatchEndedAutoPress>d__15(0) { <>4__this = this }; } private static GameObject GetRematchButton() { return Players.IsHost() ? GetHostRematchButton() : GetClientRematchButton(); } private static GameObject GetRequeueButton() { return Players.IsHost() ? GetHostRequeueButton() : GetClientRequeueButton(); } private static GameObject GetExitButton() { return Players.IsHost() ? GetHostExitButton() : GetClientExitButton(); } private static GameObject GetHostRematchButton() { return (currentScene == "Map0") ? Button.GetGameObject() : Button.GetGameObject(); } private static GameObject GetHostRequeueButton() { return (currentScene == "Map0") ? Requeuebutton.GetGameObject() : Requeuebutton.GetGameObject(); } private static GameObject GetHostExitButton() { return (currentScene == "Map0") ? Exitmatchbutton.GetGameObject() : Exitmatchbutton.GetGameObject(); } private static GameObject GetClientRematchButton() { return (currentScene == "Map0") ? Button.GetGameObject() : Button.GetGameObject(); } private static GameObject GetClientRequeueButton() { return (currentScene == "Map0") ? Requeuebutton.GetGameObject() : Requeuebutton.GetGameObject(); } private static GameObject GetClientExitButton() { return (currentScene == "Map0") ? Exitmatchbutton.GetGameObject() : Exitmatchbutton.GetGameObject(); } } public enum RematchTypes { [Display(Name = "Game Default")] None, [Display(Name = "Timed")] AutoRematch, [Display(Name = "On Fistbump")] RematchOnFistbump } public enum ControllerButtons { [Display(Name = "None")] None, [Display(Name = "Left Controller Trigger")] LeftControllerTrigger, [Display(Name = "Left Controller Primary")] LeftControllerPrimary, [Display(Name = "Left Controller Secondary")] LeftControllerSecondary, [Display(Name = "Right Controller Trigger")] RightControllerTrigger, [Display(Name = "Right Controller Primary")] RightControllerPrimary, [Display(Name = "Right Controller Secondary")] RightControllerSecondary } public enum Hand { [Display(Name = "Left Hand")] Left, [Display(Name = "Right Hand")] Right } public enum Function { [Display(Name = "Do Nothing")] None, [Display(Name = "Press Requeue")] Requeue, [Display(Name = "Press Exit")] Exit } public enum OnePlayerFunction { [Display(Name = "Do Nothing")] None, [Display(Name = "Secondary Hand Function")] SecondaryHandFunction, [Display(Name = "Press Requeue")] Requeue, [Display(Name = "Press Exit")] Exit } public class Preferences { private const string CONFIG_FILE = "config.cfg"; private const string USER_DATA = "UserData/AutomaticRematch/"; internal static Dictionary<MelonPreferences_Entry, object> LastSavedValues = new Dictionary<MelonPreferences_Entry, object>(); internal static MelonPreferences_Category AutomaticRematchCategory; internal static MelonPreferences_Entry<RematchTypes> PrefRematchType; internal static MelonPreferences_Entry<OnePlayerFunction> PrefOnePlayerRemain; internal static MelonPreferences_Entry<bool> PrefDebugging; internal static MelonPreferences_Category AutoPressSettingsCategory; internal static MelonPreferences_Entry<float> PrefTimeBeforeRematch; internal static MelonPreferences_Entry<bool> PrefPreventAutoRematchButtonEnabled; internal static MelonPreferences_Entry<ControllerButtons> PrefPreventAutoRematchButton; internal static MelonPreferences_Category FistbumpSettingsCategory; internal static MelonPreferences_Entry<Hand> PrefPrimaryHand; internal static MelonPreferences_Entry<Function> PrefSecondaryHandFunction; internal static void InitPrefs() { if (!Directory.Exists("UserData/AutomaticRematch/")) { Directory.CreateDirectory("UserData/AutomaticRematch/"); } AutomaticRematchCategory = MelonPreferences.CreateCategory("AutomaticRematch", "Rematch Type"); AutomaticRematchCategory.SetFilePath(Path.Combine("UserData/AutomaticRematch/", "config.cfg")); PrefRematchType = AutomaticRematchCategory.CreateEntry<RematchTypes>("RematchType", RematchTypes.AutoRematch, "Rematch Confirmation Type", "Selects what type of Rematch Confirmation to use", false, false, (ValueValidator)null, (string)null); PrefOnePlayerRemain = AutomaticRematchCategory.CreateEntry<OnePlayerFunction>("OnePlayerRemain", OnePlayerFunction.None, "Other Player Leaves Function", "Sets the Function for When One Player Remains", false, false, (ValueValidator)null, (string)null); PrefDebugging = AutomaticRematchCategory.CreateEntry<bool>("Debug", false, "Debugging", "Toggles Debugging On/Off", false, false, (ValueValidator)null, (string)null); AutoPressSettingsCategory = MelonPreferences.CreateCategory("TimedSettings", "Timed Settings"); AutoPressSettingsCategory.SetFilePath(Path.Combine("UserData/AutomaticRematch/", "config.cfg")); PrefTimeBeforeRematch = AutoPressSettingsCategory.CreateEntry<float>("TimeBeforeRematch", 0f, "Time Before Rematch", "Time to Wait before it Presses Rematch", false, false, (ValueValidator)(object)new ValueRange<float>(0f, float.MaxValue), (string)null); PrefPreventAutoRematchButtonEnabled = AutoPressSettingsCategory.CreateEntry<bool>("PreventAutoRematchButtonEnabled", true, "Prevent Auto Rematch Button Enabled", "Toggles Button to Stop Rematching On/Off", false, false, (ValueValidator)null, (string)null); PrefPreventAutoRematchButton = AutoPressSettingsCategory.CreateEntry<ControllerButtons>("PreventAutoRematchButton", ControllerButtons.LeftControllerTrigger, "Prevent Auto Rematch Button", "Sets What Button it Watches to Prevent Automatic Rematching", false, false, (ValueValidator)null, (string)null); FistbumpSettingsCategory = MelonPreferences.CreateCategory("FistbumpSettings", "Fistbump Settings"); FistbumpSettingsCategory.SetFilePath(Path.Combine("UserData/AutomaticRematch/", "config.cfg")); PrefPrimaryHand = FistbumpSettingsCategory.CreateEntry<Hand>("PrimaryHand", Hand.Right, "Primary Hand", "Sets the Primary Hand for Fistbump Actions", false, false, (ValueValidator)null, (string)null); PrefSecondaryHandFunction = FistbumpSettingsCategory.CreateEntry<Function>("SecondaryHandFunction", Function.None, "Secondary Hand Function", "Sets the Secondary Hand Function for Fistbump Actions", false, false, (ValueValidator)null, (string)null); StoreLastSavedPrefs(); } internal static void StoreLastSavedPrefs() { List<MelonPreferences_Entry> list = new List<MelonPreferences_Entry>(); list.AddRange(AutomaticRematchCategory.Entries); list.AddRange(AutoPressSettingsCategory.Entries); list.AddRange(FistbumpSettingsCategory.Entries); foreach (MelonPreferences_Entry item in list) { LastSavedValues[item] = item.BoxedValue; } } }