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 BetterDisconnectReasons v1.0.1
BepInEx/plugins/ZaboomafooW-BetterDisconnectReasons-v1.0.1.dll
Decompiled an hour agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Netcode.Transports.Facepunch; using Steamworks; using Steamworks.Data; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("BetterDisconnectReasons")] [assembly: AssemblyDescription("Clearer client-side disconnect messages for Lethal Company v81")] [assembly: AssemblyCompany("ZaboomafooW")] [assembly: AssemblyProduct("BetterDisconnectReasons")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BetterDisconnectReasons { internal static class ReconnectController { internal static ulong SavedHostSteamId { get; private set; } internal static Lobby SavedLobby { get; private set; } internal static bool HasSavedLobby { get; private set; } internal static bool PendingReconnect { get; private set; } internal static bool ReconnectInProgress { get; private set; } internal static ConnectionState OriginalDisconnectState { get; private set; } internal static NetConnectionEnd OriginalDisconnectEndReason { get; private set; } private static bool HasOriginalDisconnectInfo { get; set; } internal static void RecordServer(SteamId hostSteamId, GameNetworkManager gameNetworkManager) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) SavedHostSteamId = SteamId.op_Implicit(hostSteamId); if (!ReconnectInProgress) { ClearOriginalDisconnectInfo(); } if ((Object)(object)gameNetworkManager != (Object)null && gameNetworkManager.currentLobby.HasValue) { SavedLobby = gameNetworkManager.currentLobby.Value; HasSavedLobby = true; } else if (!ReconnectInProgress) { HasSavedLobby = false; } } internal static void RecordSteamDisconnect(ConnectionInfo info) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!ReconnectInProgress && !PendingReconnect && !HasOriginalDisconnectInfo) { GameNetworkManager instance = GameNetworkManager.Instance; if (!((Object)(object)instance == (Object)null) && !instance.isDisconnecting && !instance.localClientWaitingForApproval) { OriginalDisconnectState = ((ConnectionInfo)(ref info)).State; OriginalDisconnectEndReason = ((ConnectionInfo)(ref info)).EndReason; HasOriginalDisconnectInfo = true; Plugin.Log.LogInfo((object)$"[BetterDisconnectReasons] Saved Steam disconnect: state={OriginalDisconnectState}, endReason={OriginalDisconnectEndReason}."); } } } internal static void RecordUnexpectedDisconnect(GameNetworkManager gameNetworkManager) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (SavedHostSteamId == 0L) { Plugin.Log.LogWarning((object)"[BetterDisconnectReasons] Unexpected disconnect, but no host Steam ID was saved. Using vanilla handling."); return; } if ((Object)(object)gameNetworkManager != (Object)null && gameNetworkManager.currentLobby.HasValue) { SavedLobby = gameNetworkManager.currentLobby.Value; HasSavedLobby = true; } PendingReconnect = true; ReconnectInProgress = false; Plugin.Log.LogInfo((object)$"[BetterDisconnectReasons] Unexpected disconnect. Reconnecting to host {SavedHostSteamId}."); } internal static void MarkLobbyClosedForRound() { HasSavedLobby = false; } internal static void BeginReconnect() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (PendingReconnect && !ReconnectInProgress && SavedHostSteamId != 0L) { PendingReconnect = false; ReconnectInProgress = true; Plugin.Log.LogInfo((object)"[BetterDisconnectReasons] Starting reconnect."); GameNetworkManager instance = GameNetworkManager.Instance; if ((Object)(object)instance == (Object)null) { FailReconnect("Server no longer exists."); } else if (HasSavedLobby) { instance.JoinLobby(SavedLobby, SteamId.op_Implicit(SavedHostSteamId)); } else { instance.StartClient(SteamId.op_Implicit(SavedHostSteamId)); } } } internal static SteamId ResolveReconnectTarget(SteamId requestedTarget) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!ReconnectInProgress || SavedHostSteamId == 0L) { return requestedTarget; } return SteamId.op_Implicit(SavedHostSteamId); } internal static void CompleteSuccessfulReconnect() { if (ReconnectInProgress) { ReconnectInProgress = false; ClearOriginalDisconnectInfo(); Plugin.Log.LogInfo((object)"[BetterDisconnectReasons] Reconnect accepted."); } } internal static string NormalizeDisconnectionReason(string reason) { if (string.IsNullOrEmpty(reason)) { return reason; } switch (reason) { case "You cannot rejoin after being kicked.": return "You were kicked."; case "Game has already started!": if (OriginalDisconnectWasClosedByPeer()) { return "You were kicked."; } if (OriginalDisconnectWasConnectionFailure()) { return "You disconnected. The game has already started."; } return reason; case "Lobby is full!": if (OriginalDisconnectWasClosedByPeer()) { return "You were kicked."; } if (OriginalDisconnectWasConnectionFailure()) { return "You disconnected. The server is now full."; } return "Server is full."; case "The host was not accepting connections.": return "Server no longer exists."; case "Unknown; please verify your game files.": return "Connection approval request was invalid."; default: return reason; } } internal static void CompleteFailedReconnect(string displayedReason) { if (ReconnectInProgress) { ReconnectInProgress = false; Plugin.Log.LogInfo((object)("[BetterDisconnectReasons] Reconnect failed: " + displayedReason)); } } internal static void FailReconnect(string reason) { ReconnectInProgress = false; PendingReconnect = false; if ((Object)(object)GameNetworkManager.Instance != (Object)null) { GameNetworkManager.Instance.disconnectionReasonMessage = reason; } Plugin.Log.LogInfo((object)("[BetterDisconnectReasons] Could not reconnect: " + reason)); } internal static void ResetAll() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) SavedHostSteamId = 0uL; SavedLobby = default(Lobby); HasSavedLobby = false; PendingReconnect = false; ReconnectInProgress = false; ClearOriginalDisconnectInfo(); } private static bool OriginalDisconnectWasClosedByPeer() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 return (int)OriginalDisconnectState == 4; } private static bool OriginalDisconnectWasConnectionFailure() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected I4, but got Unknown if ((int)OriginalDisconnectState == 5) { return true; } int num = (int)OriginalDisconnectEndReason; if (num >= 3000) { return num <= 5999; } return false; } private static void ClearOriginalDisconnectInfo() { OriginalDisconnectState = (ConnectionState)0; OriginalDisconnectEndReason = (NetConnectionEnd)0; HasOriginalDisconnectInfo = false; } } [HarmonyPatch] internal static class GameNetworkManagerPatches { [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "StartClient")] private static void StartClientPrefix(GameNetworkManager __instance, ref SteamId id) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) id = ReconnectController.ResolveReconnectTarget(id); ReconnectController.RecordServer(id, __instance); } [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientDisconnectCallback")] private static void ClientDisconnectPrefix(GameNetworkManager __instance, ulong clientId) { NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && !((Object)(object)__instance == (Object)null) && !ReconnectController.ReconnectInProgress && !ReconnectController.PendingReconnect && !__instance.isDisconnecting && !__instance.localClientWaitingForApproval && !singleton.IsServer && singleton.IsClient && (clientId == 0L || clientId == singleton.LocalClientId)) { ReconnectController.RecordUnexpectedDisconnect(__instance); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientConnectedCallback")] private static void ClientConnectedPostfix(ulong clientId) { NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && ReconnectController.ReconnectInProgress && clientId == singleton.LocalClientId) { ReconnectController.CompleteSuccessfulReconnect(); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")] private static void LeaveLobbyAtGameStartPostfix() { ReconnectController.MarkLobbyClosedForRound(); } } [HarmonyPatch] internal static class MenuManagerPatches { [HarmonyPrefix] [HarmonyPatch(typeof(MenuManager), "Start")] private static void StartPrefix() { if (ReconnectController.PendingReconnect && !((Object)(object)GameNetworkManager.Instance == (Object)null)) { GameNetworkManager.Instance.disconnectReason = 0; GameNetworkManager.Instance.disconnectionReasonMessage = string.Empty; } } [HarmonyPostfix] [HarmonyPatch(typeof(MenuManager), "Start")] private static void StartPostfix(MenuManager __instance) { if (!((Object)(object)__instance == (Object)null) && ReconnectController.PendingReconnect) { ReconnectController.BeginReconnect(); } } [HarmonyPrefix] [HarmonyPatch(typeof(MenuManager), "SetLoadingScreen")] private static void SetLoadingScreenPrefix(bool isLoading, ref RoomEnter result, ref string overrideMessage) { if (!isLoading && ReconnectController.ReconnectInProgress) { GameNetworkManager instance = GameNetworkManager.Instance; if ((Object)(object)instance != (Object)null && !string.IsNullOrEmpty(instance.disconnectionReasonMessage)) { instance.disconnectionReasonMessage = ReconnectController.NormalizeDisconnectionReason(instance.disconnectionReasonMessage); } else if (!string.IsNullOrEmpty(overrideMessage)) { overrideMessage = "Server no longer exists."; } else if ((int)result == 5 || (int)result == 2) { overrideMessage = "Server no longer exists."; } } } [HarmonyPostfix] [HarmonyPatch(typeof(MenuManager), "SetLoadingScreen")] private static void SetLoadingScreenPostfix(bool isLoading, string overrideMessage) { if (!isLoading && ReconnectController.ReconnectInProgress) { string text = overrideMessage; if (string.IsNullOrEmpty(text) && (Object)(object)GameNetworkManager.Instance != (Object)null) { text = GameNetworkManager.Instance.disconnectionReasonMessage; } if (string.IsNullOrEmpty(text)) { text = "Server no longer exists."; } ReconnectController.CompleteFailedReconnect(text); } } } [HarmonyPatch(typeof(ConnectionManager), "OnDisconnected")] internal static class SteamConnectionPatches { [HarmonyPrefix] private static void OnDisconnectedPrefix(ConnectionManager __instance, ConnectionInfo info) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (__instance != null && __instance.Interface is FacepunchTransport) { ReconnectController.RecordSteamDisconnect(info); } } } [BepInPlugin("ZaboomafooW.BetterDisconnectReasons", "BetterDisconnectReasons", "1.0.1")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "ZaboomafooW.BetterDisconnectReasons"; public const string PluginName = "BetterDisconnectReasons"; public const string PluginVersion = "1.0.1"; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("ZaboomafooW.BetterDisconnectReasons"); _harmony.PatchAll(); Log.LogInfo((object)"[BetterDisconnectReasons] Loaded v1.0.1"); Log.LogInfo((object)"[BetterDisconnectReasons] Hook succeeded: disconnect/reconnect patches applied."); } private void OnApplicationQuit() { ReconnectController.ResetAll(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Log = null; } } }