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 BetterServerScrolling v1.0.0
BepInEx/plugins/BetterServerScrolling/ZaboomafooW-BetterServerScrolling-v1.0.0.dll
Decompiled 2 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using BetterServerScrolling.Controllers; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; 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-BetterServerScrolling-v1.0.0")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ZaboomafooW-BetterServerScrolling-v1.0.0")] [assembly: AssemblyTitle("ZaboomafooW-BetterServerScrolling-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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 BetterServerScrolling { [BepInPlugin("ZaboomafooW.BetterServerScrolling", "BetterServerScrolling", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { internal const string PluginGuid = "ZaboomafooW.BetterServerScrolling"; internal const string PluginName = "BetterServerScrolling"; internal const string PluginVersion = "1.0.0"; private Harmony? harmonyInstance; internal static ManualLogSource LogSource { 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 LogSource = ((BaseUnityPlugin)this).Logger; harmonyInstance = new Harmony("ZaboomafooW.BetterServerScrolling"); harmonyInstance.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[BetterServerScrolling] Loaded v1.0.0"); } private void OnApplicationQuit() { if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); harmonyInstance = null; } } } } namespace BetterServerScrolling.Patches { [HarmonyPatch] internal static class ServerListScrollPatches { [HarmonyPrefix] [HarmonyPatch(typeof(ScrollRect), "OnScroll")] private static void ScrollRectOnScrollPrefix(ScrollRect __instance, PointerEventData eventData) { ServerListScrollController.NormalizeServerListScrollInput(__instance, eventData); } [HarmonyPrefix] [HarmonyPatch(typeof(SteamLobbyManager), "LoadServerList")] private static void LoadServerListPrefix(SteamLobbyManager __instance) { ServerListScrollController.PrepareServerListForRefresh(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(SteamLobbyManager), "loadLobbyListAndFilter")] private static void LoadLobbyListAndFilterPostfix(SteamLobbyManager __instance, ref IEnumerator __result) { if (__result != null) { __result = ServerListScrollController.WrapServerListPopulation(__instance, __result); } } } } namespace BetterServerScrolling.Controllers { internal static class ServerListScrollController { private readonly struct ServerRowPositionSnapshot { internal RectTransform RowRectTransform { get; } internal Vector3 WorldPosition { get; } internal ServerRowPositionSnapshot(RectTransform rowRectTransform, Vector3 worldPosition) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) RowRectTransform = rowRectTransform; WorldPosition = worldPosition; } } private const float ServerRowSpacing = 42f; private const float ServerRowScrollSensitivity = 42f; private const float ServerRowPositionTolerance = 0.25f; private const float ScrollOverflowTolerance = 0.5f; private const float ServerRowsPerWheelStep = 1.5f; private static bool serverListHookLogged; private static ScrollRect? activeServerListScrollRect; private static int lastAppliedVisibleServerCount = -1; private static bool lastAppliedScrollingEnabled; private static int lastLoggedVisibleServerCount = -1; private static bool? lastLoggedScrollingEnabled; internal static void PrepareServerListForRefresh(SteamLobbyManager steamLobbyManager) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) lastAppliedVisibleServerCount = -1; if (TryGetServerListScrollContext(steamLobbyManager, out RectTransform serverListContent, out ScrollRect serverListScrollRect, out RectTransform serverListViewport)) { serverListScrollRect.StopMovement(); serverListScrollRect.movementType = (MovementType)2; serverListScrollRect.scrollSensitivity = 42f; serverListScrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1; RectTransform serverListContent2 = serverListContent; Rect rect = serverListViewport.rect; ResizeServerListContentPreservingTop(serverListContent2, ((Rect)(ref rect)).height, null); serverListScrollRect.verticalNormalizedPosition = 1f; serverListScrollRect.vertical = false; Canvas.ForceUpdateCanvases(); } } internal static IEnumerator WrapServerListPopulation(SteamLobbyManager steamLobbyManager, IEnumerator vanillaPopulationCoroutine) { while (vanillaPopulationCoroutine.MoveNext()) { ApplyCurrentServerListLayout(steamLobbyManager, populationFinished: false); yield return vanillaPopulationCoroutine.Current; } ApplyCurrentServerListLayout(steamLobbyManager, populationFinished: true); } internal static void NormalizeServerListScrollInput(ScrollRect scrollRect, PointerEventData eventData) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0068: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)scrollRect == (Object)null) && eventData != null && !((Object)(object)scrollRect != (Object)(object)activeServerListScrollRect) && scrollRect.vertical) { Vector2 scrollDelta = eventData.scrollDelta; scrollDelta.x = Mathf.Clamp(scrollDelta.x, -1f, 1f); scrollDelta.y = Mathf.Clamp(scrollDelta.y, -1f, 1f) * 1.5f; eventData.scrollDelta = scrollDelta; } } private static void ApplyCurrentServerListLayout(SteamLobbyManager steamLobbyManager, bool populationFinished) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!TryGetServerListScrollContext(steamLobbyManager, out RectTransform serverListContent, out ScrollRect serverListScrollRect, out RectTransform serverListViewport) || !TryGetVisibleServerCount(steamLobbyManager, out var visibleServerCount)) { return; } if (visibleServerCount != lastAppliedVisibleServerCount) { Rect rect = serverListViewport.rect; float height = ((Rect)(ref rect)).height; if (height <= 0f) { Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] Server list viewport height was not valid; leaving vanilla bounds unchanged."); return; } List<ServerRowPositionSnapshot> serverRowPositions = new List<ServerRowPositionSnapshot>(); float requiredContentHeight = 0f; if (visibleServerCount > 0 && !TryMeasureVisibleServerRows(serverListContent, visibleServerCount, serverRowPositions, out requiredContentHeight)) { Plugin.LogSource.LogWarning((object)string.Format("[{0}] Could not verify all {1} populated server rows; leaving vanilla bounds unchanged.", "BetterServerScrolling", visibleServerCount)); return; } float targetContentHeight = Mathf.Max(height, requiredContentHeight); bool vertical = requiredContentHeight > height + 0.5f; serverListScrollRect.StopMovement(); serverListScrollRect.movementType = (MovementType)2; serverListScrollRect.scrollSensitivity = 42f; serverListScrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1; ResizeServerListContentPreservingTop(serverListContent, targetContentHeight, serverRowPositions); serverListScrollRect.vertical = vertical; Canvas.ForceUpdateCanvases(); lastAppliedVisibleServerCount = visibleServerCount; lastAppliedScrollingEnabled = vertical; } if (populationFinished && (lastLoggedVisibleServerCount != visibleServerCount || lastLoggedScrollingEnabled != lastAppliedScrollingEnabled)) { string arg = (lastAppliedScrollingEnabled ? "enabled" : "disabled"); Plugin.LogSource.LogInfo((object)string.Format("[{0}] Corrected server list bounds for {1} visible servers; scrolling {2}.", "BetterServerScrolling", visibleServerCount, arg)); lastLoggedVisibleServerCount = visibleServerCount; lastLoggedScrollingEnabled = lastAppliedScrollingEnabled; } } private static bool TryGetServerListScrollContext(SteamLobbyManager steamLobbyManager, out RectTransform serverListContent, out ScrollRect serverListScrollRect, out RectTransform serverListViewport) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) serverListContent = null; serverListScrollRect = null; serverListViewport = null; if ((Object)(object)steamLobbyManager == (Object)null || (Object)(object)steamLobbyManager.levelListContainer == (Object)null) { return false; } Transform levelListContainer = steamLobbyManager.levelListContainer; RectTransform val = (RectTransform)(object)((levelListContainer is RectTransform) ? levelListContainer : null); if ((Object)(object)val == (Object)null) { Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] levelListContainer was not a RectTransform; leaving the server list unchanged."); return false; } ScrollRect componentInParent = ((Component)val).GetComponentInParent<ScrollRect>(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.content != (Object)(object)val) { Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] Could not match levelListContainer to its ScrollRect content; leaving the server list unchanged."); return false; } RectTransform val2 = componentInParent.viewport; if ((Object)(object)val2 == (Object)null) { Transform transform = ((Component)componentInParent).transform; val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); } if (!((Object)(object)val2 == (Object)null)) { Rect rect = val2.rect; if (!(((Rect)(ref rect)).height <= 0f)) { serverListContent = val; serverListScrollRect = componentInParent; serverListViewport = val2; activeServerListScrollRect = componentInParent; if (!serverListHookLogged) { Plugin.LogSource.LogInfo((object)"[BetterServerScrolling] Hook succeeded: matched the server list content to its ScrollRect."); serverListHookLogged = true; } return true; } } Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] Could not resolve a valid server list viewport; leaving the server list unchanged."); return false; } private static bool TryGetVisibleServerCount(SteamLobbyManager steamLobbyManager, out int visibleServerCount) { visibleServerCount = 0; try { FieldInfo field = typeof(SteamLobbyManager).GetField("lobbySlotPositionOffset", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] Could not access SteamLobbyManager.lobbySlotPositionOffset."); return false; } if (!(field.GetValue(steamLobbyManager) is float num)) { Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] SteamLobbyManager.lobbySlotPositionOffset had an unexpected value."); return false; } int num2 = Mathf.RoundToInt((0f - num) / 42f); if (num2 < 0 || Mathf.Abs(num + (float)num2 * 42f) > 0.25f) { Plugin.LogSource.LogWarning((object)"[BetterServerScrolling] Server row offset did not match the v81 42-unit placement rule."); return false; } visibleServerCount = num2; return true; } catch (Exception ex) { Plugin.LogSource.LogWarning((object)("[BetterServerScrolling] Failed to read the populated server count: " + ex.Message)); return false; } } private static bool TryMeasureVisibleServerRows(RectTransform serverListContent, int visibleServerCount, List<ServerRowPositionSnapshot> serverRowPositions, out float requiredContentHeight) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) requiredContentHeight = 0f; bool[] array = new bool[visibleServerCount]; float num = float.PositiveInfinity; for (int i = 0; i < ((Transform)serverListContent).childCount; i++) { Transform child = ((Transform)serverListContent).GetChild(i); RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null); if ((Object)(object)val == (Object)null || (Object)(object)((Component)child).GetComponentInChildren<LobbySlot>() == (Object)null) { continue; } if (!Mathf.Approximately(val.anchorMin.y, val.anchorMax.y)) { return false; } int num2 = Mathf.RoundToInt((0f - val.anchoredPosition.y) / 42f); if (num2 < 0 || num2 >= visibleServerCount) { continue; } float num3 = (float)(-num2) * 42f; if (Mathf.Abs(val.anchoredPosition.y - num3) > 0.25f) { continue; } array[num2] = true; serverRowPositions.Add(new ServerRowPositionSnapshot(val, ((Transform)val).position)); Vector3[] array2 = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array2); for (int j = 0; j < array2.Length; j++) { float y = ((Transform)serverListContent).InverseTransformPoint(array2[j]).y; if (y < num) { num = y; } } } for (int k = 0; k < array.Length; k++) { if (!array[k]) { return false; } } if (float.IsPositiveInfinity(num)) { return false; } Rect rect = serverListContent.rect; requiredContentHeight = ((Rect)(ref rect)).yMax - num; return requiredContentHeight >= 0f; } private static void ResizeServerListContentPreservingTop(RectTransform serverListContent, float targetContentHeight, List<ServerRowPositionSnapshot>? serverRowPositions) { //IL_0010: 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) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (targetContentHeight <= 0f) { return; } Rect rect = serverListContent.rect; Vector3 val = ((Transform)serverListContent).TransformPoint(new Vector3(0f, ((Rect)(ref rect)).yMax, 0f)); Vector2 sizeDelta = serverListContent.sizeDelta; ref float y = ref sizeDelta.y; float num = y; rect = serverListContent.rect; y = num + (targetContentHeight - ((Rect)(ref rect)).height); serverListContent.sizeDelta = sizeDelta; Canvas.ForceUpdateCanvases(); rect = serverListContent.rect; Vector3 val2 = ((Transform)serverListContent).TransformPoint(new Vector3(0f, ((Rect)(ref rect)).yMax, 0f)); ((Transform)serverListContent).position = ((Transform)serverListContent).position + (val - val2); if (serverRowPositions == null) { return; } for (int i = 0; i < serverRowPositions.Count; i++) { ServerRowPositionSnapshot serverRowPositionSnapshot = serverRowPositions[i]; if ((Object)(object)serverRowPositionSnapshot.RowRectTransform != (Object)null) { ((Transform)serverRowPositionSnapshot.RowRectTransform).position = serverRowPositionSnapshot.WorldPosition; } } } } }