Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of QuickReroll v3.0.3
QuotaReroll.dll
Decompiled 5 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("QuotaReroll")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("QuotaReroll")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d9c049c8-f290-4a04-853c-55008cb1c07d")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace QuickRejoin; [BepInPlugin("com.myself.quickrejoin", "Quick Rejoin Mod", "3.3.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"=== Quick Rejoin v3.3.0 Loaded ==="); GameObject val = new GameObject("QuickRejoinManager"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<RejoinManager>(); Log.LogInfo((object)"Quick Rejoin initialized"); } } internal class RejoinManager : MonoBehaviour { [CompilerGenerated] private sealed class <WaitForRerollComplete>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public RejoinManager <>4__this; private float <waitTime>5__1; private LevelGenerator <generator>5__2; private FieldInfo <generatedField>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForRerollComplete>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <generator>5__2 = null; <generatedField>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown Scene activeScene; switch (<>1__state) { default: return false; case 0: <>1__state = -1; <waitTime>5__1 = 0f; goto IL_0078; case 1: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_0078; case 2: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_00f8; case 3: { <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_01d2; } IL_0078: activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Main" && <waitTime>5__1 < 30f) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } <generator>5__2 = null; <waitTime>5__1 = 0f; goto IL_00f8; IL_01d2: if (<waitTime>5__1 < 30f) { if (!(bool)<generatedField>5__3.GetValue(<generator>5__2)) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 3; return true; } Plugin.Log.LogInfo((object)"Level generation complete!"); } goto IL_01e6; IL_01e6: <generatedField>5__3 = null; break; IL_00f8: if ((Object)(object)<generator>5__2 == (Object)null && <waitTime>5__1 < 30f) { <generator>5__2 = Object.FindObjectOfType<LevelGenerator>(); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } if (!((Object)(object)<generator>5__2 != (Object)null)) { break; } <generatedField>5__3 = typeof(LevelGenerator).GetField("Generated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (<generatedField>5__3 != null) { <waitTime>5__1 = 0f; goto IL_01d2; } goto IL_01e6; } <>4__this._isRerolling = false; Plugin.Log.LogInfo((object)"Reroll complete!"); 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 const float CheckInterval = 0.5f; private const float MaxWaitTime = 30f; internal static bool RerollQueued; internal static int QueuedSeed; internal static bool IsShopReroll; internal static bool SeedApplied; internal static Dictionary<string, int> LevelStartHealth = new Dictionary<string, int>(); internal static bool HealthSaved = false; private static Harmony _harmony; private bool _isRerolling; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Plugin.Log.LogInfo((object)"RejoinManager Awake"); _harmony = new Harmony("com.myself.quickrejoin"); _harmony.PatchAll(); Plugin.Log.LogInfo((object)"Harmony patches applied"); Plugin.Log.LogInfo((object)"Reroll key: Backslash (\\)"); Plugin.Log.LogInfo((object)"Debug key: Equals (=)"); } private void Update() { if (Input.GetKeyDown((KeyCode)92)) { TryInitiateReroll(); } if (Input.GetKeyDown((KeyCode)61)) { PrintLevelDebug(); } } private void PrintLevelDebug() { Plugin.Log.LogInfo((object)"=== LEVEL DEBUG ==="); RunManager val = Object.FindObjectOfType<RunManager>(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)"RunManager not found"); return; } FieldInfo field = typeof(RunManager).GetField("levelCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(RunManager).GetField("levelShop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object? value = field.GetValue(val); Object val2 = (Object)((value is Object) ? value : null); Plugin.Log.LogInfo((object)("Current level: " + (((val2 != null) ? val2.name : null) ?? "null"))); } if (field2 != null) { object? value2 = field2.GetValue(val); Object val3 = (Object)((value2 is Object) ? value2 : null); Plugin.Log.LogInfo((object)("Shop level: " + (((val3 != null) ? val3.name : null) ?? "null"))); } Plugin.Log.LogInfo((object)$"Is Multiplayer: {PhotonNetwork.IsConnected}"); Plugin.Log.LogInfo((object)$"Is Master Client: {PhotonNetwork.IsMasterClient}"); Plugin.Log.LogInfo((object)$"Saved level start health (HealthSaved: {HealthSaved}):"); foreach (KeyValuePair<string, int> item in LevelStartHealth) { Plugin.Log.LogInfo((object)$" {item.Key}: {item.Value}"); } if ((Object)(object)StatsManager.instance != (Object)null) { Plugin.Log.LogInfo((object)"StatsManager playerHealth:"); foreach (KeyValuePair<string, int> item2 in StatsManager.instance.playerHealth) { Plugin.Log.LogInfo((object)$" {item2.Key}: {item2.Value}"); } } Plugin.Log.LogInfo((object)"=== END DEBUG ==="); } internal static void SaveLevelStartHealth() { if (HealthSaved) { Plugin.Log.LogInfo((object)"Health already saved for this level, skipping"); return; } LevelStartHealth.Clear(); if (!((Object)(object)StatsManager.instance != (Object)null)) { return; } foreach (KeyValuePair<string, int> item in StatsManager.instance.playerHealth) { LevelStartHealth[item.Key] = item.Value; Plugin.Log.LogInfo((object)$"Saved starting health for {item.Key}: {item.Value}"); } HealthSaved = true; } private void RestoreHealthToLevelStart() { Plugin.Log.LogInfo((object)"Restoring health to level start values..."); if ((Object)(object)StatsManager.instance == (Object)null || LevelStartHealth.Count == 0) { Plugin.Log.LogWarning((object)"No saved health data to restore"); return; } foreach (KeyValuePair<string, int> item in LevelStartHealth) { StatsManager.instance.SetPlayerHealth(item.Key, item.Value, true); Plugin.Log.LogInfo((object)$"Restored health for {item.Key}: {item.Value}"); } HealthSaved = false; } private void TryInitiateReroll() { if (_isRerolling) { Plugin.Log.LogWarning((object)"Reroll already in progress"); return; } if (PhotonNetwork.IsConnected && !PhotonNetwork.IsMasterClient) { Plugin.Log.LogWarning((object)"Cannot reroll: Only host can reroll in multiplayer"); return; } RunManager val = Object.FindObjectOfType<RunManager>(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Cannot reroll: RunManager not found"); return; } FieldInfo field = typeof(RunManager).GetField("levelCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(RunManager).GetField("levels", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field3 = typeof(RunManager).GetField("levelShop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null || field3 == null) { Plugin.Log.LogWarning((object)"Cannot reroll: Could not read RunManager fields"); return; } object value = field.GetValue(val); IList list = field2.GetValue(val) as IList; object value2 = field3.GetValue(val); if (value == null || list == null) { Plugin.Log.LogWarning((object)"Cannot reroll: Level data is null"); return; } bool flag = false; bool flag2 = value == value2; foreach (object item in list) { if (item == value) { flag = true; break; } } if (!flag && !flag2) { object obj = ((value is Object) ? value : null); string text = ((obj != null) ? ((Object)obj).name : null) ?? "unknown"; Plugin.Log.LogWarning((object)("Cannot reroll: Not in a run level or shop (current: " + text + ")")); return; } Plugin.Log.LogInfo((object)(">>> " + (flag2 ? "SHOP " : "") + "REROLL INITIATED <<<")); int num = Random.Range(int.MinValue, int.MaxValue); Plugin.Log.LogInfo((object)$"New seed: {num}"); QueuedSeed = num; RerollQueued = true; IsShopReroll = flag2; SeedApplied = false; _isRerolling = true; RestoreHealthToLevelStart(); if (flag2) { val.ChangeLevel(false, false, (ChangeLevelType)5); } else { val.ChangeLevel(false, false, (ChangeLevelType)1); } ((MonoBehaviour)this).StartCoroutine(WaitForRerollComplete()); } [IteratorStateMachine(typeof(<WaitForRerollComplete>d__16))] private IEnumerator WaitForRerollComplete() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForRerollComplete>d__16(0) { <>4__this = this }; } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(RunManager), "SetRunLevel")] internal static class RunManager_SetRunLevel_Patch { private static bool Prefix(RunManager __instance) { if (!RejoinManager.RerollQueued || RejoinManager.IsShopReroll) { return true; } Plugin.Log.LogInfo((object)$"[HARMONY] Overriding SetRunLevel with seed: {RejoinManager.QueuedSeed}"); FieldInfo field = typeof(RunManager).GetField("levels", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(RunManager).GetField("levelCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null) { Plugin.Log.LogError((object)"Could not find required fields!"); return true; } if (!(field.GetValue(__instance) is IList list) || list.Count == 0) { Plugin.Log.LogError((object)"Levels list is null or empty!"); return true; } Random.InitState(RejoinManager.QueuedSeed); RejoinManager.SeedApplied = true; int num = Random.Range(0, list.Count); object obj = list[num]; field2.SetValue(__instance, obj); object obj2 = ((obj is Object) ? obj : null); string arg = ((obj2 != null) ? ((Object)obj2).name : null) ?? "unknown"; Plugin.Log.LogInfo((object)$"[HARMONY] Selected level [{num}]: {arg}"); RejoinManager.RerollQueued = false; return false; } } [HarmonyPatch(typeof(LevelGenerator), "Generate")] internal static class LevelGenerator_Generate_Patch { private static void Prefix() { if (RejoinManager.RerollQueued && !RejoinManager.SeedApplied) { Plugin.Log.LogInfo((object)$"[HARMONY] Seeding RNG before Generate: {RejoinManager.QueuedSeed}"); Random.InitState(RejoinManager.QueuedSeed); RejoinManager.SeedApplied = true; if (!RejoinManager.IsShopReroll) { RejoinManager.RerollQueued = false; } } } } [HarmonyPatch(typeof(ShopManager), "ShopInitialize")] internal static class ShopManager_ShopInitialize_Patch { private static void Prefix() { if (RejoinManager.RerollQueued && RejoinManager.IsShopReroll && !RejoinManager.SeedApplied) { Plugin.Log.LogInfo((object)$"[HARMONY] Seeding RNG before ShopInitialize: {RejoinManager.QueuedSeed}"); Random.InitState(RejoinManager.QueuedSeed); RejoinManager.SeedApplied = true; } if (RejoinManager.IsShopReroll) { RejoinManager.RerollQueued = false; RejoinManager.IsShopReroll = false; } } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] internal static class LevelGenerator_GenerateDone_Patch { [CompilerGenerated] private sealed class <SaveHealthDelayed>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SaveHealthDelayed>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 1; return true; case 1: <>1__state = -1; RejoinManager.SaveLevelStartHealth(); 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 void Postfix() { Plugin.Log.LogInfo((object)"[HARMONY] GenerateDone called, saving level start health..."); if ((Object)(object)LevelGenerator.Instance != (Object)null) { ((MonoBehaviour)LevelGenerator.Instance).StartCoroutine(SaveHealthDelayed()); } } [IteratorStateMachine(typeof(<SaveHealthDelayed>d__1))] private static IEnumerator SaveHealthDelayed() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SaveHealthDelayed>d__1(0); } }