using 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 TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ZaboomafooW-BetterLoadingScreen-v1.0.0")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ZaboomafooW-BetterLoadingScreen-v1.0.0")] [assembly: AssemblyTitle("ZaboomafooW-BetterLoadingScreen-v1.0.0")] [assembly: AssemblyVersion("1.0.0.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 ZaboomafooW.BetterLoadingScreen { internal static class LoadingStatusController { private static MenuManager menuManager; private static bool active; private static bool featureExecutionLogged; private static string currentStatus; private static string previousStatus; private static string oldestStatus; private static bool originalTextLayoutCaptured; private static bool originalWordWrapping; private static bool originalAutoSizing; private static float originalFontSizeMin; private static float originalFontSizeMax; private static float originalRectHeight; private static Vector2 originalSizeDelta; private static Vector2 originalAnchoredPosition; private static TextOverflowModes originalOverflowMode; internal static void BeginServerLookup() { Begin("Getting server information..."); } internal static void BeginDirectConnection() { Begin("Contacting server..."); } internal static void AttachMenu(MenuManager instance) { if (active && !((Object)(object)instance == (Object)null)) { menuManager = instance; ApplyHistoryLayout(); Render(); } } internal static void End() { if ((Object)(object)menuManager != (Object)null && (Object)(object)menuManager.loadingText != (Object)null) { ((TMP_Text)menuManager.loadingText).OnPreRenderText -= ApplyVerticalAlphaGradient; } RestoreTextLayout(); active = false; menuManager = null; currentStatus = null; previousStatus = null; oldestStatus = null; } internal static void Shutdown() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) End(); featureExecutionLogged = false; originalWordWrapping = false; originalAutoSizing = false; originalFontSizeMin = 0f; originalFontSizeMax = 0f; originalRectHeight = 0f; originalSizeDelta = default(Vector2); originalAnchoredPosition = default(Vector2); originalOverflowMode = (TextOverflowModes)0; } internal static void RequestingLobbyAccess() { SetStatus("Requesting lobby access..."); } internal static void ContactingServer() { SetStatus("Contacting server..."); } internal static void WaitingForServerReply() { SetStatus("Waiting for server reply..."); } internal static void JoiningServer() { SetStatus("Joining server..."); } private static void Begin(string status) { currentStatus = null; previousStatus = null; oldestStatus = null; active = true; menuManager = Object.FindObjectOfType(); SetStatus(status); } private static void SetStatus(string status) { if (active && !string.IsNullOrWhiteSpace(status) && !string.Equals(currentStatus, status, StringComparison.Ordinal)) { oldestStatus = previousStatus; previousStatus = currentStatus; currentStatus = status; Render(); } } private static void ApplyHistoryLayout() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)menuManager == (Object)null) && !((Object)(object)menuManager.loadingText == (Object)null)) { TextMeshProUGUI loadingText = menuManager.loadingText; RectTransform rectTransform = ((TMP_Text)loadingText).rectTransform; Rect rect; if (!originalTextLayoutCaptured) { originalWordWrapping = ((TMP_Text)loadingText).enableWordWrapping; originalAutoSizing = ((TMP_Text)loadingText).enableAutoSizing; originalFontSizeMin = ((TMP_Text)loadingText).fontSizeMin; originalFontSizeMax = ((TMP_Text)loadingText).fontSizeMax; rect = rectTransform.rect; originalRectHeight = ((Rect)(ref rect)).height; originalSizeDelta = rectTransform.sizeDelta; originalAnchoredPosition = rectTransform.anchoredPosition; originalOverflowMode = ((TMP_Text)loadingText).overflowMode; originalTextLayoutCaptured = true; } ((TMP_Text)loadingText).enableWordWrapping = false; ((TMP_Text)loadingText).overflowMode = (TextOverflowModes)0; ((TMP_Text)loadingText).enableAutoSizing = true; ((TMP_Text)loadingText).fontSizeMin = 12f; ((TMP_Text)loadingText).fontSizeMax = Mathf.Max(((TMP_Text)loadingText).fontSize, 12f); Canvas canvas = ((Graphic)loadingText).canvas; RectTransform val = (RectTransform)(((Object)(object)canvas != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { rect = val.rect; float num = ((Rect)(ref rect)).width * 0.9f; rectTransform.SetSizeWithCurrentAnchors((Axis)0, num); } float num2 = Mathf.Max(originalRectHeight * 3f, ((TMP_Text)loadingText).fontSize * 4f); rectTransform.SetSizeWithCurrentAnchors((Axis)1, num2); rectTransform.anchoredPosition = originalAnchoredPosition; } } private static void RestoreTextLayout() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) if (originalTextLayoutCaptured) { if ((Object)(object)menuManager != (Object)null && (Object)(object)menuManager.loadingText != (Object)null) { TextMeshProUGUI loadingText = menuManager.loadingText; ((TMP_Text)loadingText).enableWordWrapping = originalWordWrapping; ((TMP_Text)loadingText).enableAutoSizing = originalAutoSizing; ((TMP_Text)loadingText).fontSizeMin = originalFontSizeMin; ((TMP_Text)loadingText).fontSizeMax = originalFontSizeMax; ((TMP_Text)loadingText).overflowMode = originalOverflowMode; ((TMP_Text)loadingText).rectTransform.sizeDelta = originalSizeDelta; ((TMP_Text)loadingText).rectTransform.anchoredPosition = originalAnchoredPosition; } originalTextLayoutCaptured = false; } } private static void ApplyVerticalAlphaGradient(TMP_TextInfo textInfo) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if (!active || textInfo == null || textInfo.lineCount < 1) { return; } float ascender = textInfo.lineInfo[0].ascender; float descender = textInfo.lineInfo[textInfo.lineCount - 1].descender; float num = ascender - descender; if (num <= Mathf.Epsilon) { return; } for (int i = 0; i < textInfo.characterCount; i++) { TMP_CharacterInfo val = textInfo.characterInfo[i]; if (val.isVisible) { TMP_MeshInfo val2 = textInfo.meshInfo[val.materialReferenceIndex]; int vertexIndex = val.vertexIndex; for (int j = 0; j < 4; j++) { int num2 = vertexIndex + j; float num3 = Mathf.Clamp01((ascender - val2.vertices[num2].y) / num); Color32 val3 = val2.colors32[num2]; val3.a = (byte)Mathf.RoundToInt((float)(int)val3.a * num3); val2.colors32[num2] = val3; } } } } private static void Render() { if (active && !string.IsNullOrEmpty(currentStatus) && !((Object)(object)menuManager == (Object)null) && !((Object)(object)menuManager.loadingScreen == (Object)null) && menuManager.loadingScreen.activeInHierarchy && !((Object)(object)menuManager.loadingText == (Object)null)) { ApplyHistoryLayout(); string text = oldestStatus ?? string.Empty; string text2 = previousStatus ?? string.Empty; TextMeshProUGUI loadingText = menuManager.loadingText; ((TMP_Text)loadingText).OnPreRenderText -= ApplyVerticalAlphaGradient; ((TMP_Text)loadingText).OnPreRenderText += ApplyVerticalAlphaGradient; ((TMP_Text)loadingText).text = text + "\n" + text2 + "\n" + currentStatus; if (!featureExecutionLogged) { featureExecutionLogged = true; Plugin.Log.LogInfo((object)"[BetterLoadingScreen] Replaced the vanilla server-join loading text."); } } } } [HarmonyPatch(typeof(LobbySlot), "JoinLobbyAfterVerifying")] internal static class JoinLobbyAfterVerifyingPatch { private static void Prefix() { LoadingStatusController.BeginServerLookup(); } } [HarmonyPatch(typeof(GameNetworkManager), "JoinLobby")] internal static class JoinLobbyPatch { private static void Prefix() { LoadingStatusController.RequestingLobbyAccess(); } } [HarmonyPatch(typeof(NetworkManager), "StartClient")] internal static class NetworkManagerStartClientPatch { private static void Prefix() { LoadingStatusController.ContactingServer(); } } [HarmonyPatch(typeof(MenuManager), "SetLoadingScreen")] internal static class SetLoadingScreenPatch { private static void Postfix(MenuManager __instance, bool isLoading) { if (isLoading) { LoadingStatusController.AttachMenu(__instance); } else { LoadingStatusController.End(); } } } [HarmonyPatch(typeof(MenuManager), "StartAClient")] internal static class StartAClientPatch { private static void Prefix() { LoadingStatusController.BeginDirectConnection(); } } internal static class VerifiedConnectionPatches { private const BindingFlags InstanceNonPublic = BindingFlags.Instance | BindingFlags.NonPublic; private const BindingFlags InstancePublic = BindingFlags.Instance | BindingFlags.Public; private const BindingFlags StaticNonPublic = BindingFlags.Static | BindingFlags.NonPublic; internal static bool Apply(Harmony harmony) { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown if (harmony == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Cannot apply verified connection hooks because the Harmony instance is null."); return false; } try { Assembly assembly = typeof(NetworkManager).Assembly; Type type = assembly.GetType("Unity.Netcode.NetworkConnectionManager", throwOnError: false); if (type == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Verified v81 type Unity.Netcode.NetworkConnectionManager was not found."); return false; } Type type2 = assembly.GetType("Unity.Netcode.ConnectionApprovedMessage", throwOnError: false); if (type2 == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Verified v81 type Unity.Netcode.ConnectionApprovedMessage was not found."); return false; } MethodInfo method = type.GetMethod("SendConnectionRequest", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Verified v81 method NetworkConnectionManager.SendConnectionRequest was not found."); return false; } MethodInfo method2 = type2.GetMethod("Handle", BindingFlags.Instance | BindingFlags.Public); if (method2 == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Verified v81 method ConnectionApprovedMessage.Handle was not found."); return false; } MethodInfo method3 = typeof(VerifiedConnectionPatches).GetMethod("ConnectionRequestPostfix", BindingFlags.Static | BindingFlags.NonPublic); if (method3 == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Internal patch method VerifiedConnectionPatches.ConnectionRequestPostfix was not found."); return false; } MethodInfo method4 = typeof(VerifiedConnectionPatches).GetMethod("ConnectionApprovedHandlePrefix", BindingFlags.Static | BindingFlags.NonPublic); if (method4 == null) { Plugin.Log.LogError((object)"[BetterLoadingScreen] Internal patch method VerifiedConnectionPatches.ConnectionApprovedHandlePrefix was not found."); return false; } harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)method2, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("[BetterLoadingScreen] Failed to apply verified v81 connection hooks: " + ex)); return false; } } private static void ConnectionRequestPostfix() { LoadingStatusController.WaitingForServerReply(); } private static void ConnectionApprovedHandlePrefix() { LoadingStatusController.JoiningServer(); } } [BepInPlugin("ZaboomafooW.BetterLoadingScreen", "Better Loading Screen", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "ZaboomafooW.BetterLoadingScreen"; public const string PluginName = "Better Loading Screen"; public const string PluginVersion = "1.0.0"; private Harmony harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"[BetterLoadingScreen] Loaded v1.0.0"); harmony = new Harmony("ZaboomafooW.BetterLoadingScreen"); try { harmony.PatchAll(); if (!VerifiedConnectionPatches.Apply(harmony)) { harmony.UnpatchSelf(); Log.LogError((object)"[BetterLoadingScreen] Loading-screen hooks were not fully applied; mod hooks were disabled."); return; } } catch (Exception ex) { harmony.UnpatchSelf(); Log.LogError((object)("[BetterLoadingScreen] Failed to apply loading-screen hooks; mod hooks were disabled: " + ex)); return; } Log.LogInfo((object)"[BetterLoadingScreen] Hooked verified server-join loading status updates."); } private void OnApplicationQuit() { LoadingStatusController.Shutdown(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; Log = null; } } }