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 LC Rehoster v1.0.0
BepInEx/plugins/LC-ReHoster.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; 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: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] namespace HostRestartFix; [BepInPlugin("net.vanilla.hostrestartfix", "HostRestartFix", "1.0.0")] public class Plugin : BaseUnityPlugin { private class DebugLogPatch { private static bool betaSaveDataDetected; private static bool hostStartDetected; private static void Prefix(object message) { if (message != null) { string text = message.ToString(); if (text.Contains("host")) { logger.LogInfo((object)("Host-related message detected: '" + text + "'")); } if (text.Contains("Has beta save data")) { logger.LogInfo((object)("Beta save data message detected: '" + text + "'")); betaSaveDataDetected = true; CheckBothConditions(); } if (text.Contains("[Info : Unity Log] started host!") || text.Contains("started host") || (text.Contains("host") && text.Contains("start"))) { logger.LogInfo((object)("Host start message detected: '" + text + "'")); logger.LogInfo((object)$"Current flags - hasBeenForceQuit: {hasBeenForceQuit}, firstHostDetected: {firstHostDetected}, betaSaveDataDetected: {betaSaveDataDetected}"); hostStartDetected = true; CheckBothConditions(); } } } private static void CheckBothConditions() { logger.LogInfo((object)$"Checking both conditions - hostStartDetected: {hostStartDetected}, betaSaveDataDetected: {betaSaveDataDetected}, hasBeenForceQuit: {hasBeenForceQuit}"); if (!hasBeenForceQuit && hostStartDetected && betaSaveDataDetected) { logger.LogInfo((object)"Both conditions met! Will force quit to menu in 10 seconds."); firstHostDetected = true; if (!((Object)(object)Instance == (Object)null)) { try { logger.LogInfo((object)"Starting ForceQuitToMenu coroutine"); ((MonoBehaviour)Instance).StartCoroutine(ForceQuitToMenu()); logger.LogInfo((object)"Coroutine started successfully"); return; } catch (Exception ex) { logger.LogError((object)("Failed to start coroutine: " + ex.Message)); logger.LogError((object)ex.StackTrace); hasBeenForceQuit = true; ForceReturnToMainMenu(); return; } } logger.LogError((object)"Plugin Instance is null! Cannot start coroutine!"); } else { logger.LogInfo((object)$"Not all conditions met: hostStartDetected={hostStartDetected}, betaSaveDataDetected={betaSaveDataDetected}, hasBeenForceQuit={hasBeenForceQuit}"); } } } [CompilerGenerated] private sealed class <ForceQuitToMenu>d__13 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private float <timer>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ForceQuitToMenu>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; logger.LogInfo((object)"ForceQuitToMenu coroutine started"); if ((Object)(object)messageObject != (Object)null) { messageObject.SetActive(true); if ((Object)(object)messageText != (Object)null) { ((TMP_Text)messageText).text = "The Mods have Pre-loaded. Returning to menu in 10 seconds.\nPlease re-host the game for proper weather loading."; } logger.LogInfo((object)"Message displayed"); } else { logger.LogError((object)"messageObject is null!"); } <timer>5__1 = 10f; goto IL_0145; case 1: <>1__state = -1; <timer>5__1--; goto IL_0145; case 2: <>1__state = -1; logger.LogInfo((object)"Showing completion message"); if ((Object)(object)messageObject != (Object)null && (Object)(object)messageText != (Object)null) { messageObject.SetActive(true); ((TMP_Text)messageText).text = "Please start hosting again for proper weather loading."; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 3; return true; } break; case 3: { <>1__state = -1; messageObject.SetActive(false); break; } IL_0145: if (<timer>5__1 > 0f) { if ((Object)(object)messageText != (Object)null) { ((TMP_Text)messageText).text = $"The Mods have Pre-loaded. Returning to menu in {<timer>5__1:0} seconds.\nPlease re-host the game for proper weather loading."; } logger.LogInfo((object)$"Timer: {<timer>5__1}"); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } logger.LogInfo((object)"Timer completed, setting hasBeenForceQuit=true"); hasBeenForceQuit = true; if ((Object)(object)messageObject != (Object)null) { messageObject.SetActive(false); } logger.LogInfo((object)"Calling ForceReturnToMainMenu"); ForceReturnToMainMenu(); <>2__current = (object)new WaitForSeconds(2f); <>1__state = 2; return true; } logger.LogInfo((object)"ForceQuitToMenu coroutine completed successfully"); 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(); } } internal static ManualLogSource logger; private static bool firstHostDetected; private static bool hasBeenForceQuit; private static GameObject messageObject; private static TextMeshProUGUI messageText; internal static Plugin Instance; internal static ConfigEntry<Key> RestartKey; private static bool keyPressedNow; private void Awake() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) logger = ((BaseUnityPlugin)this).Logger; logger.LogInfo((object)"Plugin net.vanilla.hostrestartfix is loaded!"); Instance = this; logger.LogInfo((object)"Plugin instance set"); RestartKey = ((BaseUnityPlugin)this).Config.Bind<Key>("General", "RestartKey", (Key)32, "This key, when pressed in combination with Ctrl+Shift+Alt, will force return to main menu (useful if mods break)"); try { Harmony val = new Harmony("net.vanilla.hostrestartfix"); MethodInfo methodInfo = AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(object) }, (Type[])null); if (methodInfo == null) { logger.LogError((object)"Failed to find Debug.Log method to patch!"); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(DebugLogPatch), "Prefix", (Type[])null, (Type[])null); if (methodInfo2 == null) { logger.LogError((object)"Failed to find prefix method for patching!"); return; } val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); logger.LogInfo((object)"Debug.Log patch applied successfully"); val.PatchAll(Assembly.GetExecutingAssembly()); logger.LogInfo((object)"All patches applied successfully"); } catch (Exception ex) { logger.LogError((object)("Failed to apply Harmony patch: " + ex.Message)); logger.LogError((object)ex.StackTrace); return; } try { GameObject val2 = new GameObject("RestartFixMessageCanvas"); Object.DontDestroyOnLoad((Object)(object)val2); Canvas val3 = val2.AddComponent<Canvas>(); val3.renderMode = (RenderMode)0; val3.sortingOrder = 10000; messageObject = new GameObject("RestartFixMessage"); messageObject.transform.SetParent(((Component)val3).transform, false); RectTransform val4 = messageObject.AddComponent<RectTransform>(); val4.anchorMin = new Vector2(0.5f, 0.5f); val4.anchorMax = new Vector2(0.5f, 0.5f); val4.pivot = new Vector2(0.5f, 0.5f); val4.sizeDelta = new Vector2(800f, 100f); messageText = messageObject.AddComponent<TextMeshProUGUI>(); ((TMP_Text)messageText).fontSize = 24f; ((TMP_Text)messageText).alignment = (TextAlignmentOptions)514; ((Graphic)messageText).color = Color.red; ((TMP_Text)messageText).text = ""; messageObject.SetActive(false); logger.LogInfo((object)"UI components created successfully"); } catch (Exception ex2) { logger.LogError((object)("Error creating UI: " + ex2.Message)); } try { GameObject val5 = new GameObject("ReHosterKeyHandler"); val5.AddComponent<KeybindHandlerBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val5); logger.LogInfo((object)"Keybind handler created successfully"); } catch (Exception ex3) { logger.LogError((object)("Error creating keybind handler: " + ex3.Message)); } hasBeenForceQuit = false; firstHostDetected = false; logger.LogInfo((object)("Flags reset: hasBeenForceQuit=" + hasBeenForceQuit)); } private void Update() { if (Keyboard.current != null) { CheckForceRestartKeybind(); } } public static void CheckForceRestartKeybind() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (Keyboard.current == null) { return; } if (Keyboard.current.ctrlKey.isPressed && Keyboard.current.altKey.isPressed && Keyboard.current.shiftKey.isPressed) { KeyControl val = ((IEnumerable<KeyControl>)(object)Keyboard.current.allKeys).FirstOrDefault((Func<KeyControl, bool>)((KeyControl key) => key.keyCode == RestartKey.Value)); if (val != null && ((ButtonControl)val).isPressed) { if (!keyPressedNow) { logger.LogInfo((object)"Force restart keybind pressed!"); ForceReturnToMainMenu(); } keyPressedNow = true; } else { keyPressedNow = false; } } else { keyPressedNow = false; } } public static void ForceReturnToMainMenu() { logger.LogInfo((object)"ForceReturnToMainMenu called"); if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsConnectedClient) { try { GameNetworkManager instance = GameNetworkManager.Instance; if (instance != null) { instance.Disconnect(); } logger.LogInfo((object)"Attempted clean disconnect through GameNetworkManager"); } catch (Exception ex) { logger.LogError((object)("Error during disconnect: " + ex.Message)); } try { NetworkManager.Singleton.Shutdown(false); logger.LogInfo((object)"Force shutdown NetworkManager"); } catch (Exception ex2) { logger.LogError((object)("Error during NetworkManager shutdown: " + ex2.Message)); } } else { logger.LogInfo((object)"Not connected to network or NetworkManager.Singleton is null"); } if ((Object)(object)GameNetworkManager.Instance != (Object)null) { try { MethodInfo method = typeof(GameNetworkManager).GetMethod("ResetGameValuesToDefault", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { method.Invoke(GameNetworkManager.Instance, new object[0]); logger.LogInfo((object)"Reset game values to default"); } else { logger.LogError((object)"ResetGameValuesToDefault method not found"); } } catch (Exception ex3) { logger.LogError((object)("Error resetting game values: " + ex3.Message)); } } else { logger.LogInfo((object)"GameNetworkManager.Instance is null"); } try { logger.LogInfo((object)"Attempting to load main menu scene by index"); SceneManager.LoadScene(0); logger.LogInfo((object)"Loaded main menu scene"); } catch (Exception ex4) { logger.LogError((object)("Error loading main menu scene: " + ex4.Message)); try { logger.LogInfo((object)"Attempting to load main menu scene by name"); SceneManager.LoadScene("MainMenu"); logger.LogInfo((object)"Loaded main menu scene by name"); } catch (Exception ex5) { logger.LogError((object)("Error loading main menu scene by name: " + ex5.Message)); } } } [IteratorStateMachine(typeof(<ForceQuitToMenu>d__13))] private static IEnumerator ForceQuitToMenu() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ForceQuitToMenu>d__13(0); } } public class KeybindHandlerBehaviour : MonoBehaviour { private void Update() { Plugin.CheckForceRestartKeybind(); } } [HarmonyPatch] internal class ReHosterPatches { [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Start")] public static void InGameSetup() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown GameObject val = GameObject.Find("ReHosterKeyHandler"); if ((Object)(object)val == (Object)null) { val = new GameObject("ReHosterKeyHandler"); val.AddComponent<KeybindHandlerBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val); Plugin.logger.LogInfo((object)"Created KeybindHandlerBehaviour in game scene"); } } } public static class PluginInfo { public const string PLUGIN_GUID = "net.vanilla.hostrestartfix"; public const string PLUGIN_NAME = "HostRestartFix"; public const string PLUGIN_VERSION = "1.0.0"; }