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 QuickRejoin v3.0.0
QuotaReroll.dll
Decompiled 8 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 ExitGames.Client.Photon; using HarmonyLib; using Photon.Pun; using Photon.Realtime; 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.0.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.0.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 <RerollCoroutine>d__22 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public bool isShop; public bool isHost; public RejoinManager <>4__this; private float <waitTime>5__1; private RunManager <runManager>5__2; private string <currentScene>5__3; private bool <sceneChanged>5__4; private string <newScene>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RerollCoroutine>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <runManager>5__2 = null; <currentScene>5__3 = null; <newScene>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: 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) //IL_00b7: Expected O, but got Unknown //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Expected O, but got Unknown //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Expected O, but got Unknown //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown Scene activeScene; switch (<>1__state) { default: return false; case 0: <>1__state = -1; Plugin.Log.LogInfo((object)string.Format("Starting {0}reroll sequence (Host: {1})...", isShop ? "shop " : "", isHost)); <waitTime>5__1 = 0f; goto IL_00da; case 1: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_00da; case 2: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_01b4; case 3: <>1__state = -1; <waitTime>5__1 += 0.5f; activeScene = SceneManager.GetActiveScene(); <newScene>5__5 = ((Scene)(ref activeScene)).name; if (<newScene>5__5 != <currentScene>5__3) { <sceneChanged>5__4 = true; Plugin.Log.LogInfo((object)("Scene change detected: " + <currentScene>5__3 + " -> " + <newScene>5__5)); } <newScene>5__5 = null; goto IL_033a; case 4: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_03d2; case 5: <>1__state = -1; break; case 6: { <>1__state = -1; break; } IL_01b4: while ((Object)(object)<runManager>5__2 == (Object)null && <waitTime>5__1 < 30f) { <runManager>5__2 = Object.FindObjectOfType<RunManager>(); if ((Object)(object)<runManager>5__2 == (Object)null) { Plugin.Log.LogInfo((object)"Waiting for RunManager..."); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } } if ((Object)(object)<runManager>5__2 == (Object)null) { Plugin.Log.LogError((object)"Timeout waiting for RunManager!"); <>4__this.ResetState(); return false; } if (isShop) { Plugin.Log.LogInfo((object)"Host reloading shop..."); <runManager>5__2.ChangeLevel(false, false, (ChangeLevelType)5); } else { Plugin.Log.LogInfo((object)"Host calling RunManager.ChangeLevel..."); <runManager>5__2.ChangeLevel(false, false, (ChangeLevelType)1); } <runManager>5__2 = null; goto IL_0391; IL_0391: <waitTime>5__1 = 0f; goto IL_03d2; IL_033a: if (!<sceneChanged>5__4 && <waitTime>5__1 < 30f) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 3; return true; } if (!<sceneChanged>5__4) { Plugin.Log.LogWarning((object)"Timeout waiting for scene change from host"); <>4__this.ResetState(); return false; } <currentScene>5__3 = null; goto IL_0391; IL_03d2: activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Main" && <waitTime>5__1 < 30f) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 4; return true; } activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Main") { Plugin.Log.LogWarning((object)"Timeout waiting for Main scene"); <>4__this.ResetState(); return false; } Plugin.Log.LogInfo((object)"Main scene loaded, waiting for level generation..."); if (isShop) { <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.WaitForShopReady()); <>1__state = 5; return true; } <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.WaitForLevelReady()); <>1__state = 6; return true; IL_00da: if (!PhotonNetwork.IsConnectedAndReady && PhotonNetwork.IsConnected && <waitTime>5__1 < 30f) { Plugin.Log.LogInfo((object)"Waiting for Photon connection to be ready..."); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } if (<waitTime>5__1 >= 30f) { Plugin.Log.LogError((object)"Timeout waiting for Photon connection!"); <>4__this.ResetState(); return false; } if (isHost) { <runManager>5__2 = null; <waitTime>5__1 = 0f; goto IL_01b4; } Plugin.Log.LogInfo((object)"Client waiting for host to change level..."); activeScene = SceneManager.GetActiveScene(); <currentScene>5__3 = ((Scene)(ref activeScene)).name; <waitTime>5__1 = 0f; <sceneChanged>5__4 = false; goto IL_033a; } Plugin.Log.LogInfo((object)"Reroll complete!"); <>4__this.ResetState(); 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 <WaitForLevelReady>d__23 : 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; private bool <generated>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForLevelReady>d__23(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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <waitTime>5__1 = 0f; <generator>5__2 = null; goto IL_00ac; case 1: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_00ac; case 2: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_01a2; case 3: { <>1__state = -1; break; } IL_00ac: while ((Object)(object)<generator>5__2 == (Object)null && <waitTime>5__1 < 30f) { <generator>5__2 = Object.FindObjectOfType<LevelGenerator>(); if ((Object)(object)<generator>5__2 == (Object)null) { Plugin.Log.LogInfo((object)"Waiting for LevelGenerator..."); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } } if ((Object)(object)<generator>5__2 == (Object)null) { Plugin.Log.LogWarning((object)"Timeout waiting for LevelGenerator"); return false; } <generatedField>5__3 = typeof(LevelGenerator).GetField("Generated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (<generatedField>5__3 != null) { <waitTime>5__1 = 0f; goto IL_01a2; } Plugin.Log.LogInfo((object)"Could not find Generated field, waiting 3 seconds..."); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 3; return true; IL_01a2: if (<waitTime>5__1 < 30f) { <generated>5__4 = (bool)<generatedField>5__3.GetValue(<generator>5__2); if (<generated>5__4) { Plugin.Log.LogInfo((object)"Level generation complete!"); return false; } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } Plugin.Log.LogWarning((object)"Timeout waiting for level generation"); 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(); } } [CompilerGenerated] private sealed class <WaitForShopReady>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public RejoinManager <>4__this; private float <waitTime>5__1; private ShopManager <shopManager>5__2; private FieldInfo <shoppingListField>5__3; private IList <shoppingList>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForShopReady>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <shopManager>5__2 = null; <shoppingListField>5__3 = null; <shoppingList>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <waitTime>5__1 = 0f; <shopManager>5__2 = null; goto IL_00ac; case 1: <>1__state = -1; <waitTime>5__1 += 0.5f; goto IL_00ac; case 2: <>1__state = -1; <waitTime>5__1 += 0.5f; <shoppingList>5__4 = null; goto IL_01d4; case 3: { <>1__state = -1; break; } IL_00ac: while ((Object)(object)<shopManager>5__2 == (Object)null && <waitTime>5__1 < 30f) { <shopManager>5__2 = Object.FindObjectOfType<ShopManager>(); if ((Object)(object)<shopManager>5__2 == (Object)null) { Plugin.Log.LogInfo((object)"Waiting for ShopManager..."); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } } if ((Object)(object)<shopManager>5__2 == (Object)null) { Plugin.Log.LogWarning((object)"Timeout waiting for ShopManager"); return false; } <shoppingListField>5__3 = typeof(ShopManager).GetField("shoppingList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (<shoppingListField>5__3 != null) { <waitTime>5__1 = 0f; goto IL_01d4; } Plugin.Log.LogInfo((object)"Could not find shoppingList field, waiting 3 seconds..."); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 3; return true; IL_01d4: if (<waitTime>5__1 < 30f) { <shoppingList>5__4 = <shoppingListField>5__3.GetValue(<shopManager>5__2) as IList; if (<shoppingList>5__4 != null && <shoppingList>5__4.Count > 0) { Plugin.Log.LogInfo((object)$"Shop ready with {<shoppingList>5__4.Count} items!"); return false; } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } Plugin.Log.LogWarning((object)"Timeout waiting for shop to populate"); 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 const byte RerollEventCode = 42; private const float CheckInterval = 0.5f; private const float MaxWaitTime = 30f; internal static bool RerollQueued; internal static int QueuedSeed; internal static bool IsShopReroll; private static Harmony _harmony; private bool _eventsRegistered; private bool _isRerolling; private int _lastProcessedSeed; private float _lastRerollTime; 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 OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void Start() { RegisterPhotonEvents(); } private void RegisterPhotonEvents() { if (!_eventsRegistered && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived += OnEventReceived; _eventsRegistered = true; Plugin.Log.LogInfo((object)"Photon events registered"); } } private void Update() { if (!_eventsRegistered) { RegisterPhotonEvents(); } 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("levels", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.GetValue(val) is IList list) { Plugin.Log.LogInfo((object)$"Available levels ({list.Count}):"); for (int i = 0; i < list.Count; i++) { object obj = list[i]; string arg = obj?.ToString() ?? "null"; Object val2 = (Object)((obj is Object) ? obj : null); if (val2 != null) { arg = val2.name; } Plugin.Log.LogInfo((object)$" [{i}] {arg}"); } } FieldInfo field2 = typeof(RunManager).GetField("levelCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field3 = typeof(RunManager).GetField("previousRunLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field4 = typeof(RunManager).GetField("levelShop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null) { object? value = field2.GetValue(val); Object val3 = (Object)((value is Object) ? value : null); Plugin.Log.LogInfo((object)("Current level: " + (((val3 != null) ? val3.name : null) ?? "null"))); } if (field3 != null) { object? value2 = field3.GetValue(val); Object val4 = (Object)((value2 is Object) ? value2 : null); Plugin.Log.LogInfo((object)("Previous run level: " + (((val4 != null) ? val4.name : null) ?? "null"))); } if (field4 != null) { object? value3 = field4.GetValue(val); Object val5 = (Object)((value3 is Object) ? value3 : null); Plugin.Log.LogInfo((object)("Shop level: " + (((val5 != null) ? val5.name : null) ?? "null"))); } Plugin.Log.LogInfo((object)$"Is Multiplayer: {PhotonNetwork.IsConnected}"); Plugin.Log.LogInfo((object)$"Is Master Client: {PhotonNetwork.IsMasterClient}"); PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>(); Plugin.Log.LogInfo((object)$"PlayerHealth instances: {array.Length}"); PlayerHealth[] array2 = array; foreach (PlayerHealth obj2 in array2) { FieldInfo field5 = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field6 = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field5 != null && field6 != null) { int num = (int)field5.GetValue(obj2); int num2 = (int)field6.GetValue(obj2); Plugin.Log.LogInfo((object)$" Player health: {num}/{num2}"); } } Plugin.Log.LogInfo((object)"=== END DEBUG ==="); } private void TryInitiateReroll() { if (_isRerolling) { Plugin.Log.LogWarning((object)"Reroll already in progress"); 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; } if (PhotonNetwork.IsConnected && !PhotonNetwork.IsMasterClient) { Plugin.Log.LogWarning((object)"Cannot reroll: Only host can initiate reroll in multiplayer"); return; } if (PhotonNetwork.IsConnected) { Plugin.Log.LogInfo((object)(">>> MULTIPLAYER " + (flag2 ? "SHOP " : "") + "REROLL INITIATED (HOST) <<<")); } else { Plugin.Log.LogInfo((object)(">>> SINGLEPLAYER " + (flag2 ? "SHOP " : "") + "REROLL INITIATED <<<")); } int num = Random.Range(int.MinValue, int.MaxValue); Plugin.Log.LogInfo((object)$"New seed: {num}"); if (PhotonNetwork.IsConnected) { BroadcastReroll(num, flag2); } else { TriggerReroll(num, flag2, isHost: true); } } private void BroadcastReroll(int seed, bool isShop) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)$"[BROADCAST] Seed: {seed}, IsShop: {isShop}"); object[] array = new object[2] { seed, isShop }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)1, CachingOption = (EventCaching)0 }; PhotonNetwork.RaiseEvent((byte)42, (object)array, val, SendOptions.SendReliable); } private void TriggerReroll(int seed, bool isShop, bool isHost) { if (!_isRerolling && (seed != _lastProcessedSeed || !(Time.time - _lastRerollTime < 5f))) { _isRerolling = true; _lastProcessedSeed = seed; _lastRerollTime = Time.time; Plugin.Log.LogInfo((object)$"[TRIGGER] Reroll with seed: {seed}, IsShop: {isShop}, IsHost: {isHost}"); QueuedSeed = seed; RerollQueued = true; IsShopReroll = isShop; ResetAllPlayerHealth(); ((MonoBehaviour)this).StartCoroutine(RerollCoroutine(isShop, isHost)); } } private void ResetAllPlayerHealth() { Plugin.Log.LogInfo((object)"Resetting player health..."); PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>(); FieldInfo field = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field3 = typeof(PlayerHealth).GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null) { Plugin.Log.LogWarning((object)"Could not find health fields via reflection"); return; } PlayerHealth[] array2 = array; foreach (PlayerHealth obj in array2) { try { int num = (int)field.GetValue(obj); int num2 = (int)field2.GetValue(obj); if (num < num2) { field.SetValue(obj, num2); if (field3 != null && (Object)(object)StatsManager.instance != (Object)null) { object? value = field3.GetValue(obj); PlayerAvatar val = (PlayerAvatar)((value is PlayerAvatar) ? value : null); if ((Object)(object)val != (Object)null) { string text = SemiFunc.PlayerGetSteamID(val); if (!string.IsNullOrEmpty(text)) { StatsManager.instance.SetPlayerHealth(text, num2, true); Plugin.Log.LogInfo((object)$"Reset health for player {text}: {num} -> {num2}"); } } } else { Plugin.Log.LogInfo((object)$"Reset health via reflection: {num} -> {num2}"); } } else { Plugin.Log.LogInfo((object)$"Player health already at max: {num}/{num2}"); } } catch (Exception ex) { Plugin.Log.LogError((object)("Error resetting player health: " + ex.Message)); } } } [IteratorStateMachine(typeof(<RerollCoroutine>d__22))] private IEnumerator RerollCoroutine(bool isShop, bool isHost) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RerollCoroutine>d__22(0) { <>4__this = this, isShop = isShop, isHost = isHost }; } [IteratorStateMachine(typeof(<WaitForLevelReady>d__23))] private IEnumerator WaitForLevelReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForLevelReady>d__23(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<WaitForShopReady>d__24))] private IEnumerator WaitForShopReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForShopReady>d__24(0) { <>4__this = this }; } private void ResetState() { _isRerolling = false; RerollQueued = false; IsShopReroll = false; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Plugin.Log.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name)); _eventsRegistered = false; RegisterPhotonEvents(); } private void OnEventReceived(EventData photonEvent) { if (photonEvent.Code == 42) { object[] array = (object[])photonEvent.CustomData; int num = (int)array[0]; bool flag = (bool)array[1]; bool isMasterClient = PhotonNetwork.IsMasterClient; if (num != _lastProcessedSeed || Time.time - _lastRerollTime >= 5f) { Plugin.Log.LogInfo((object)$"[RECEIVED] Reroll event - Seed: {num}, IsShop: {flag}, AmHost: {isMasterClient}"); } TriggerReroll(num, flag, isMasterClient); } } private void OnDestroy() { Plugin.Log.LogWarning((object)"RejoinManager destroyed"); SceneManager.sceneLoaded -= OnSceneLoaded; if (PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= OnEventReceived; } 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 levels or levelCurrent field!"); 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); 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}"); return false; } } [HarmonyPatch(typeof(LevelGenerator), "Generate")] internal static class LevelGenerator_Generate_Patch { private static void Prefix() { if (RejoinManager.RerollQueued) { Plugin.Log.LogInfo((object)$"[HARMONY] Seeding RNG before Generate: {RejoinManager.QueuedSeed}"); Random.InitState(RejoinManager.QueuedSeed); 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) { Plugin.Log.LogInfo((object)$"[HARMONY] Seeding RNG before ShopInitialize: {RejoinManager.QueuedSeed}"); Random.InitState(RejoinManager.QueuedSeed); RejoinManager.RerollQueued = false; RejoinManager.IsShopReroll = false; } } }