Decompiled source of BiggerLobbyWithUI v1.0.0

BiggerLobbyWithUI.dll

Decompiled 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using Bifrost.ConstEnum;
using BiggerLobby;
using BiggerLobby.Patches;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using ReluProtocol.Enum;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyTitle("BiggerLobby")]
[assembly: AssemblyProduct("BiggerLobby")]
[assembly: AssemblyCompany("dsh")]
[assembly: HarmonyDontPatchAll]
[assembly: MelonInfo(typeof(Core), "BiggerLobby", "0.1.0", "dsh", null)]
[assembly: MelonGame("ReLUGames", "MIMESIS")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace BiggerLobby
{
	public sealed class Core : MelonMod
	{
		internal static Core Instance { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			ModPreferences.Initialize();
			if (!ModPreferences.Enabled)
			{
				MelonLogger.Msg("BiggerLobby 已在配置中禁用,跳过补丁。");
				return;
			}
			ApplyPatches();
			MelonLogger.Msg($"[BiggerLobby] 配置:MaxPlayers={ModPreferences.MaxPlayers}, MenuColumns={ModPreferences.MenuColumns}, " + $"ResultColumns={ModPreferences.ResultColumns}, ResultTopOffset={ModPreferences.ResultTopOffset}, DebugPlaceholders={ModPreferences.DebugPlaceholders}");
			MelonLogger.Msg($"[BiggerLobby] 人数上限 {ModPreferences.MaxPlayers},界面最多 {Math.Min(ModPreferences.MaxPlayers, 16)} 行。");
			if (ModPreferences.ResultColumns <= 4 && ModPreferences.MaxPlayers > 8)
			{
				MelonLogger.Msg("[BiggerLobby] 提示:ResultColumns=4 时结算界面会排成 4×4;想要 8×2 请把配置改成 ResultColumns = 8 后重启。");
			}
		}

		private void ApplyPatches()
		{
			int num = 0;
			Type[] types = typeof(Core).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Any())
				{
					try
					{
						((MelonBase)this).HarmonyInstance.PatchAll(type);
						num++;
					}
					catch (Exception arg)
					{
						MelonLogger.Error($"补丁类 {type.Name} 应用失败:{arg}");
					}
				}
			}
			MelonLogger.Msg($"Harmony 补丁完成:{num} 个补丁类,{((MelonBase)this).HarmonyInstance.GetPatchedMethods().Count()} 个方法。");
		}

		public override void OnUpdate()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (ModPreferences.DebugPlaceholders)
			{
				Keyboard current = Keyboard.current;
				if (current != null && ((ButtonControl)current[ModPreferences.DebugResultKey]).wasPressedThisFrame)
				{
					DebugTools.ShowFakeSurvivalResult();
				}
			}
		}

		public override void OnDeinitializeMelon()
		{
			try
			{
				((MelonBase)this).HarmonyInstance.UnpatchSelf();
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("卸载补丁时出错:" + ex.Message);
			}
		}
	}
	internal static class DebugTools
	{
		private static object? _uiPrefabs;

		private static MethodInfo? _showDialog;

		internal static void ShowFakeSurvivalResult()
		{
			try
			{
				Hub s = Hub.s;
				if ((Object)(object)s == (Object)null || (Object)(object)Hub.Main == (Object)null)
				{
					MelonLogger.Msg("[BiggerLobby] 当前不在游戏中,无法打开结算界面。");
					return;
				}
				object obj = AccessTools.Property(typeof(Hub), "tableman")?.GetValue(s);
				if (obj == null)
				{
					MelonLogger.Warning("[BiggerLobby] 找不到 TableManager。");
					return;
				}
				if (_uiPrefabs == null)
				{
					_uiPrefabs = AccessTools.Field(obj.GetType(), "uiprefabs")?.GetValue(obj);
				}
				if (_uiPrefabs == null)
				{
					MelonLogger.Warning("[BiggerLobby] 找不到 MMUIPrefabTable。");
					return;
				}
				if ((object)_showDialog == null)
				{
					_showDialog = AccessTools.Method(_uiPrefabs.GetType(), "ShowTimerDialog", new Type[3]
					{
						typeof(string),
						typeof(float),
						typeof(object[])
					}, (Type[])null);
				}
				if (_showDialog == null)
				{
					MelonLogger.Warning("[BiggerLobby] 找不到 ShowTimerDialog。");
					return;
				}
				object[] array = SurvivalResultPatch.BuildDebugParameters(Mathf.Min(ModPreferences.MaxPlayers, 16));
				if (array == null)
				{
					MelonLogger.Warning("[BiggerLobby] 结算界面调试参数构造失败。");
					return;
				}
				_showDialog.Invoke(_uiPrefabs, new object[3] { "SurvivalResult", 0f, array });
				MelonLogger.Msg("[BiggerLobby] 已打开 16 人结算界面(调试占位数据)。");
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[BiggerLobby] 打开调试结算界面失败:" + (ex.InnerException?.Message ?? ex.Message));
			}
		}
	}
	internal static class ModPreferences
	{
		private const string CategoryId = "BiggerLobby";

		private const string CategoryDisplayName = "BiggerLobby";

		private static MelonPreferences_Category? _category;

		private static MelonPreferences_Entry<bool>? _enabled;

		private static MelonPreferences_Entry<bool>? _verbose;

		private static MelonPreferences_Entry<int>? _maxPlayers;

		private static MelonPreferences_Entry<bool>? _debugPlaceholders;

		private static MelonPreferences_Entry<string>? _debugResultKey;

		private static MelonPreferences_Entry<bool>? _showSlotLabel;

		private static MelonPreferences_Entry<bool>? _showSteamId;

		private static MelonPreferences_Entry<int>? _menuColumns;

		private static MelonPreferences_Entry<float>? _menuScale;

		private static MelonPreferences_Entry<int>? _resultColumns;

		private static MelonPreferences_Entry<float>? _resultScale;

		private static MelonPreferences_Entry<float>? _resultTopOffset;

		private static MelonPreferences_Entry<int>? _spectatorColumns;

		private static MelonPreferences_Entry<float>? _spectatorScale;

		private static MelonPreferences_Entry<float>? _spectatorOffsetX;

		private static MelonPreferences_Entry<float>? _spectatorOffsetY;

		private static MelonPreferences_Entry<bool>? _spectatorFillByColumn;

		private static MelonPreferences_Entry<bool>? _showFullSpectatorName;

		internal static bool Enabled => Entry(ref _enabled).Value;

		internal static bool Verbose => Entry(ref _verbose).Value;

		internal static int MaxPlayers => Mathf.Clamp(Entry(ref _maxPlayers).Value, 2, 32);

		internal static bool DebugPlaceholders => Entry(ref _debugPlaceholders).Value;

		internal static Key DebugResultKey
		{
			get
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				if (!Enum.TryParse<Key>(Entry(ref _debugResultKey).Value, ignoreCase: true, out Key result))
				{
					return (Key)103;
				}
				return result;
			}
		}

		internal static bool ShowSlotLabel => Entry(ref _showSlotLabel).Value;

		internal static bool ShowSteamId => Entry(ref _showSteamId).Value;

		internal static int MenuColumns => Mathf.Clamp(Entry(ref _menuColumns).Value, 1, 4);

		internal static float MenuScale => Mathf.Clamp(Entry(ref _menuScale).Value, 0f, 2f);

		internal static int ResultColumns => Mathf.Clamp(Entry(ref _resultColumns).Value, 1, 8);

		internal static float ResultScale => Mathf.Clamp(Entry(ref _resultScale).Value, 0f, 2f);

		internal static float ResultTopOffset => Mathf.Clamp(Entry(ref _resultTopOffset).Value, -2000f, 2000f);

		internal static int SpectatorColumns => Mathf.Clamp(Entry(ref _spectatorColumns).Value, 1, 8);

		internal static float SpectatorScale => Mathf.Clamp(Entry(ref _spectatorScale).Value, 0f, 2f);

		internal static float SpectatorOffsetX => Mathf.Clamp(Entry(ref _spectatorOffsetX).Value, -2000f, 2000f);

		internal static float SpectatorOffsetY => Mathf.Clamp(Entry(ref _spectatorOffsetY).Value, -2000f, 2000f);

		internal static bool SpectatorFillByColumn => Entry(ref _spectatorFillByColumn).Value;

		internal static bool ShowFullSpectatorName => Entry(ref _showFullSpectatorName).Value;

		internal static void Initialize()
		{
			if (_category == null)
			{
				_category = MelonPreferences.CreateCategory("BiggerLobby", "BiggerLobby");
				_enabled = CreateEntry("Enabled", defaultValue: true, "Enabled", "Enable BiggerLobby. When disabled, no patches are applied.");
				_verbose = CreateEntry("Verbose", defaultValue: false, "Verbose logging", "Log extra diagnostics to the MelonLoader console.");
				_maxPlayers = CreateEntry("MaxPlayers", 20, "Max players", "Lobby / session player limit (2 - 32). The UI shows at most 16.");
				_debugPlaceholders = CreateEntry("DebugPlaceholders", defaultValue: false, "Debug: fill UI with placeholders", "Fill every UI slot with fake players so you can check alignment and scaling while playing alone.");
				_debugResultKey = CreateEntry("DebugResultKey", "F10", "Debug: result screen hotkey", "Key that opens the survival result screen with 16 placeholder players (only when DebugPlaceholders = true).");
				_showSlotLabel = CreateEntry("ShowSlotLabel", defaultValue: true, "Show slot number", "Draw the slot number (and optionally the SteamID) on each player row.");
				_showSteamId = CreateEntry("ShowSteamId", defaultValue: false, "Show SteamID", "Show the player's SteamID under the slot number.");
				_menuColumns = CreateEntry("MenuColumns", 2, "Player list columns", "How many columns the in-game menu player list is laid out in (1 - 4).");
				_menuScale = CreateEntry("MenuScale", 0f, "Player list scale (0 = auto)", "Row scale of the menu player list. 0 = fit the list area automatically.");
				_resultColumns = CreateEntry("ResultColumns", 8, "Result screen columns", "How many columns the survival result screen is laid out in (1 - 8).");
				_spectatorColumns = CreateEntry("SpectatorColumns", 2, "Spectator list columns", "Columns of the spectator player list (1 - 8). 16 players with 2 = 2 x 8.");
				_spectatorScale = CreateEntry("SpectatorScale", 0f, "Spectator list scale (0 = auto)", "Row scale of the spectator list. 0 = fit the list area automatically.");
				_spectatorOffsetX = CreateEntry("SpectatorOffsetX", 0f, "Spectator list offset X", "Horizontal offset of the spectator list in pixels.");
				_spectatorOffsetY = CreateEntry("SpectatorOffsetY", 0f, "Spectator list offset Y", "Vertical offset of the spectator list in pixels (positive = lower).");
				_spectatorFillByColumn = CreateEntry("SpectatorFillByColumn", defaultValue: true, "Spectator list fill by column", "Fill the first column top-to-bottom before the second column.");
				_showFullSpectatorName = CreateEntry("ShowFullSpectatorName", defaultValue: true, "Show full spectated name", "Expand the centered spectated-player name so long names are not truncated.");
				_resultTopOffset = CreateEntry("ResultTopOffset", -50f, "Result top offset (pixels)", "Pixels added to the auto-aligned top edge (positive = lower, negative = higher). 0 aligns with the vanilla 4-column position.");
				_resultScale = CreateEntry("ResultScale", 0f, "Result screen scale (0 = auto)", "Column scale of the result screen. 0 = fit the screen area automatically.");
			}
		}

		internal static void Log(string message)
		{
			if (Verbose)
			{
				MelonLogger.Msg(message);
			}
		}

		private static MelonPreferences_Entry<T> Entry<T>(ref MelonPreferences_Entry<T>? field)
		{
			if (field == null)
			{
				throw new InvalidOperationException("ModPreferences.Initialize() must run before preferences are read.");
			}
			return field;
		}

		private static MelonPreferences_Entry<T> CreateEntry<T>(string identifier, T defaultValue, string displayName, string? description = null)
		{
			if (_category == null)
			{
				throw new InvalidOperationException("Preference category not initialized.");
			}
			return _category.CreateEntry<T>(identifier, defaultValue, displayName, description, false, false, (ValueValidator)null, (string)null);
		}
	}
	internal static class UiUtil
	{
		internal static void DisableLayoutGroups(RectTransform area)
		{
			LayoutGroup[] components = ((Component)area).GetComponents<LayoutGroup>();
			for (int i = 0; i < components.Length; i++)
			{
				((Behaviour)components[i]).enabled = false;
			}
			ContentSizeFitter[] components2 = ((Component)area).GetComponents<ContentSizeFitter>();
			for (int i = 0; i < components2.Length; i++)
			{
				((Behaviour)components2[i]).enabled = false;
			}
		}

		internal static void RestoreLayout(RectTransform area)
		{
			LayoutGroup[] components = ((Component)area).GetComponents<LayoutGroup>();
			for (int i = 0; i < components.Length; i++)
			{
				((Behaviour)components[i]).enabled = true;
			}
			ContentSizeFitter[] components2 = ((Component)area).GetComponents<ContentSizeFitter>();
			for (int i = 0; i < components2.Length; i++)
			{
				((Behaviour)components2[i]).enabled = true;
			}
			UiGridLayout component = ((Component)area).GetComponent<UiGridLayout>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(area);
		}

		internal static void LayoutGrid(IReadOnlyList<RectTransform?> items, int visible, RectTransform area, Vector2 areaSize, Vector2 natural, int columns, float scaleOverride, float topOffset = 0f, float offsetX = 0f, bool byColumn = false)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)area == (Object)null || items.Count == 0)
			{
				return;
			}
			int num = Mathf.Clamp(columns, 1, 8);
			int num2 = Mathf.Max(1, Mathf.CeilToInt((float)visible / (float)num));
			float x = areaSize.x;
			float y = areaSize.y;
			if (x < 1f || y < 1f)
			{
				return;
			}
			float num3 = Mathf.Clamp(topOffset, (0f - y) * 0.5f, y * 0.9f);
			float num4 = Mathf.Max(1f, y - num3);
			float num5 = ((scaleOverride > 0f) ? scaleOverride : Mathf.Min(new float[3]
			{
				1f,
				x / ((float)num * natural.x),
				num4 / ((float)num2 * natural.y)
			}));
			num5 = Mathf.Clamp(num5, 0.05f, 2f);
			float num6 = natural.x * num5;
			float num7 = natural.y * num5;
			float num8 = (x - (float)num * num6) * 0.5f + offsetX;
			for (int i = 0; i < items.Count; i++)
			{
				RectTransform val = items[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				bool flag = i < visible;
				if (((Component)val).gameObject.activeSelf != flag)
				{
					((Component)val).gameObject.SetActive(flag);
				}
				if (flag)
				{
					int num9;
					int num10;
					if (byColumn)
					{
						num9 = i / num2;
						num10 = i % num2;
					}
					else
					{
						num9 = i % num;
						num10 = i / num;
					}
					if (num9 >= num)
					{
						num9 = num - 1;
					}
					val.anchorMin = new Vector2(0f, 1f);
					val.anchorMax = new Vector2(0f, 1f);
					val.pivot = new Vector2(0f, 1f);
					val.sizeDelta = natural;
					((Transform)val).localScale = new Vector3(num5, num5, 1f);
					val.anchoredPosition = new Vector2(num8 + (float)num9 * num6, 0f - (float)num10 * num7 - num3);
				}
			}
		}

		internal static TMP_Text CreateLabel(Transform parent, TMP_FontAsset? font, string name, float fontSize)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val2).font = font;
			}
			((TMP_Text)val2).fontSize = fontSize;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)260;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
			RectTransform val3 = (RectTransform)val.transform;
			val3.anchorMin = new Vector2(1f, 1f);
			val3.anchorMax = new Vector2(1f, 1f);
			val3.pivot = new Vector2(1f, 1f);
			val3.anchoredPosition = new Vector2(-8f, -6f);
			val3.sizeDelta = new Vector2(460f, 26f);
			return (TMP_Text)(object)val2;
		}
	}
	internal sealed class UiGridLayout : MonoBehaviour
	{
		private RectTransform _area;

		private RectTransform? _fallback;

		private List<RectTransform?> _items = new List<RectTransform>();

		private int _visible;

		private Vector2 _natural;

		private int _columns;

		private float _scale;

		private float _topOffset;

		private float _offsetX;

		private bool _byColumn;

		private int _frames;

		internal static void Schedule(RectTransform area, List<RectTransform?> items, int visible, Vector2 natural, int columns, float scale, RectTransform? fallback = null, float topOffset = 0f, float offsetX = 0f, bool byColumn = false)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)area == (Object)null) && items.Count != 0)
			{
				UiGridLayout uiGridLayout = ((Component)area).GetComponent<UiGridLayout>();
				if ((Object)(object)uiGridLayout == (Object)null)
				{
					uiGridLayout = ((Component)area).gameObject.AddComponent<UiGridLayout>();
				}
				uiGridLayout._area = area;
				uiGridLayout._fallback = fallback;
				uiGridLayout._items = items;
				uiGridLayout._visible = visible;
				uiGridLayout._natural = natural;
				uiGridLayout._columns = columns;
				uiGridLayout._scale = scale;
				uiGridLayout._topOffset = topOffset;
				uiGridLayout._offsetX = offsetX;
				uiGridLayout._byColumn = byColumn;
				uiGridLayout._frames = 0;
				((Behaviour)uiGridLayout).enabled = true;
			}
		}

		private void LateUpdate()
		{
			//IL_0058: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_area == (Object)null || !((Component)_area).gameObject.activeInHierarchy)
			{
				return;
			}
			_frames++;
			if (_frames <= 2)
			{
				Canvas.ForceUpdateCanvases();
				return;
			}
			if (_frames == 3)
			{
				UiUtil.DisableLayoutGroups(_area);
			}
			Rect rect = _area.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			string text = "area";
			if (size.x < 1f || size.y < 1f)
			{
				if ((Object)(object)_fallback != (Object)null)
				{
					rect = _fallback.rect;
					if (((Rect)(ref rect)).width >= 1f)
					{
						rect = _fallback.rect;
						if (((Rect)(ref rect)).height >= 1f)
						{
							rect = _fallback.rect;
							size = ((Rect)(ref rect)).size;
							text = "fallback:" + ((Object)_fallback).name;
							goto IL_0110;
						}
					}
				}
				((Vector2)(ref size))..ctor((float)Screen.width, (float)Screen.height);
				text = "screen";
			}
			goto IL_0110;
			IL_0110:
			if (_frames == 3)
			{
				MelonLogger.Msg($"[BiggerLobby] 网格排布 area='{((Object)_area).name}' size={size} (来源 {text}), items={_items.Count}, visible={_visible}, cols={_columns}");
			}
			UiUtil.LayoutGrid(_items, _visible, _area, size, _natural, _columns, _scale, _topOffset, _offsetX, _byColumn);
		}
	}
}
namespace BiggerLobby.Patches
{
	[HarmonyPatch(typeof(UIPrefab_InGameMenu_new))]
	internal static class InGameMenuPatch
	{
		internal const int UiSlots = 16;

		private static readonly Color PlaceholderColor = new Color(1f, 1f, 1f, 0.35f);

		private static readonly FieldInfo? PlayerItemsField = AccessTools.Field(typeof(UIPrefab_InGameMenu_new), "playerItems");

		private static readonly FieldInfo? PlayerInfosField = AccessTools.Field(typeof(UIPrefab_InGameMenu_new), "playerInfos");

		private static readonly MethodInfo? SpeakMethod = AccessTools.Method(typeof(UIPrefab_InGameMenu_new), "OnClickSpeakButton", (Type[])null, (Type[])null);

		private static readonly MethodInfo? KickMethod = AccessTools.Method(typeof(UIPrefab_InGameMenu_new), "OpenKickPlayerPopup", (Type[])null, (Type[])null);

		private static readonly Dictionary<UIPrefab_InGameMenuPlayerInfo, TMP_Text> SlotLabels = new Dictionary<UIPrefab_InGameMenuPlayerInfo, TMP_Text>();

		private static readonly Dictionary<TMP_Text, Color> OriginalColors = new Dictionary<TMP_Text, Color>();

		private static FieldInfo? _steamIdField;

		private static Type? _steamIdType;

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(UIPrefab_InGameMenu_new __instance)
		{
			try
			{
				ExpandRows(__instance);
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[BiggerLobby] 扩展玩家列表失败:{arg}");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetRemoteVolumeController_v2")]
		private static void RefreshPostfix(UIPrefab_InGameMenu_new __instance)
		{
			try
			{
				Refresh(__instance);
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[BiggerLobby] 刷新玩家列表失败:{arg}");
			}
		}

		private static void ExpandRows(UIPrefab_InGameMenu_new menu)
		{
			UIPrefab_InGameMenuPlayerInfo[] items = GetItems(menu);
			if (items == null || items.Length == 0 || items.Length >= 16)
			{
				return;
			}
			UIPrefab_InGameMenuPlayerInfo val = items[^1];
			if ((Object)(object)val == (Object)null || PlayerItemsField == null)
			{
				return;
			}
			Transform parent = ((Component)val).transform.parent;
			List<UIPrefab_InGameMenuPlayerInfo> list = new List<UIPrefab_InGameMenuPlayerInfo>(items);
			while (list.Count < 16)
			{
				int index = list.Count;
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)obj).name = "PlayerList" + (index + 1);
				obj.SetActive(true);
				UIPrefab_InGameMenuPlayerInfo component = obj.GetComponent<UIPrefab_InGameMenuPlayerInfo>();
				if ((Object)(object)component == (Object)null)
				{
					break;
				}
				component.SetIsLocalPlayer(false);
				component.OnUI_Button_Icon_volume = delegate
				{
					InvokeMenu(menu, SpeakMethod, index);
				};
				component.OnUI_Button_IconBox_kick = delegate
				{
					InvokeMenu(menu, KickMethod, index);
				};
				list.Add(component);
			}
			PlayerItemsField.SetValue(menu, list.ToArray());
			ModPreferences.Log($"[BiggerLobby] 玩家列表行数:{items.Length} -> {list.Count}");
		}

		private static void Refresh(UIPrefab_InGameMenu_new menu)
		{
			UIPrefab_InGameMenuPlayerInfo[] items = GetItems(menu);
			if (items == null || items.Length == 0)
			{
				return;
			}
			IList infos = GetInfos(menu);
			int num = Mathf.Min(infos?.Count ?? 0, items.Length);
			int num2 = Mathf.Min(ModPreferences.MaxPlayers, 16);
			bool debugPlaceholders = ModPreferences.DebugPlaceholders;
			int visible = Mathf.Min(debugPlaceholders ? num2 : num, items.Length);
			for (int i = 0; i < items.Length; i++)
			{
				UIPrefab_InGameMenuPlayerInfo val = items[i];
				if (!((Object)(object)val == (Object)null))
				{
					if (i < num)
					{
						RestoreRow(val);
						UpdateSlotLabel(val, i, GetSteamId(infos, i), placeholder: false);
					}
					else if (debugPlaceholders && i < num2)
					{
						MakePlaceholder(val, i);
						UpdateSlotLabel(val, i, string.Empty, placeholder: true);
					}
					else
					{
						((Component)val).gameObject.SetActive(false);
						SetLabelVisible(val, visible: false);
					}
				}
			}
			ScheduleLayout(items, visible);
		}

		private static void RestoreRow(UIPrefab_InGameMenuPlayerInfo row)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text uE_UI_Text = row.UE_UI_Text;
			if ((Object)(object)uE_UI_Text != (Object)null && OriginalColors.TryGetValue(uE_UI_Text, out var value))
			{
				((Graphic)uE_UI_Text).color = value;
			}
		}

		private static void MakePlaceholder(UIPrefab_InGameMenuPlayerInfo row, int index)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			((Component)row).gameObject.SetActive(true);
			TMP_Text uE_UI_Text = row.UE_UI_Text;
			if ((Object)(object)uE_UI_Text != (Object)null)
			{
				if (!OriginalColors.ContainsKey(uE_UI_Text))
				{
					OriginalColors[uE_UI_Text] = ((Graphic)uE_UI_Text).color;
				}
				uE_UI_Text.text = $"PLAYER {index + 1:D2}";
				((Graphic)uE_UI_Text).color = PlaceholderColor;
			}
			Button uE_UI_Button_IconBox_kick = row.UE_UI_Button_IconBox_kick;
			if ((Object)(object)uE_UI_Button_IconBox_kick != (Object)null)
			{
				((Component)uE_UI_Button_IconBox_kick).gameObject.SetActive(false);
			}
			Button uE_UI_Button_Icon_volume = row.UE_UI_Button_Icon_volume;
			if ((Object)(object)uE_UI_Button_Icon_volume != (Object)null)
			{
				((Component)uE_UI_Button_Icon_volume).gameObject.SetActive(true);
			}
			Slider uE_UI_Slider = row.UE_UI_Slider;
			if ((Object)(object)uE_UI_Slider != (Object)null)
			{
				((Component)uE_UI_Slider).gameObject.SetActive(true);
				uE_UI_Slider.SetValueWithoutNotify(0.5f);
			}
		}

		private static void UpdateSlotLabel(UIPrefab_InGameMenuPlayerInfo row, int index, string steamId, bool placeholder)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (!SlotLabels.TryGetValue(row, out TMP_Text value) || (Object)(object)value == (Object)null)
			{
				TMP_Text uE_UI_Text = row.UE_UI_Text;
				float fontSize = (((Object)(object)uE_UI_Text != (Object)null) ? Mathf.Max(12f, uE_UI_Text.fontSize * 0.55f) : 16f);
				value = UiUtil.CreateLabel(((Component)row).transform, ((Object)(object)uE_UI_Text != (Object)null) ? uE_UI_Text.font : null, "BiggerLobbySlot", fontSize);
				SlotLabels[row] = value;
			}
			string text = $"#{index + 1:D2}";
			if (!placeholder && ModPreferences.ShowSteamId && !string.IsNullOrEmpty(steamId) && steamId != "0")
			{
				text = text + "\n" + steamId;
			}
			value.text = text;
			((Graphic)value).color = (Color)(placeholder ? PlaceholderColor : new Color(1f, 1f, 1f, 0.8f));
			((Component)value).gameObject.SetActive(ModPreferences.ShowSlotLabel);
		}

		private static void SetLabelVisible(UIPrefab_InGameMenuPlayerInfo row, bool visible)
		{
			if (SlotLabels.TryGetValue(row, out TMP_Text value) && (Object)(object)value != (Object)null)
			{
				((Component)value).gameObject.SetActive(visible && ModPreferences.ShowSlotLabel);
			}
		}

		private static void ScheduleLayout(UIPrefab_InGameMenuPlayerInfo[] items, int visible)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(((Object)(object)items[0] != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			RectTransform val2 = (RectTransform)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || visible <= 0)
			{
				return;
			}
			if (visible <= 4)
			{
				UiUtil.RestoreLayout(val2);
				return;
			}
			Rect rect = val.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			if (size.x < 1f || size.y < 1f)
			{
				((Vector2)(ref size))..ctor(720f, 92f);
			}
			List<RectTransform> items2 = ((IEnumerable<UIPrefab_InGameMenuPlayerInfo>)items).Select((Func<UIPrefab_InGameMenuPlayerInfo, RectTransform>)delegate(UIPrefab_InGameMenuPlayerInfo item)
			{
				if (!((Object)(object)item != (Object)null))
				{
					return (RectTransform)null;
				}
				Transform transform = ((Component)item).transform;
				return (RectTransform)(object)((transform is RectTransform) ? transform : null);
			}).ToList();
			UiGridLayout.Schedule(val2, items2, visible, size, ModPreferences.MenuColumns, ModPreferences.MenuScale);
		}

		private static UIPrefab_InGameMenuPlayerInfo[]? GetItems(UIPrefab_InGameMenu_new menu)
		{
			return PlayerItemsField?.GetValue(menu) as UIPrefab_InGameMenuPlayerInfo[];
		}

		private static IList? GetInfos(UIPrefab_InGameMenu_new menu)
		{
			return PlayerInfosField?.GetValue(menu) as IList;
		}

		private static string GetSteamId(IList? infos, int index)
		{
			if (infos == null || index < 0 || index >= infos.Count)
			{
				return string.Empty;
			}
			object obj = infos[index];
			if (obj == null)
			{
				return string.Empty;
			}
			Type type = obj.GetType();
			if (_steamIdType != type)
			{
				_steamIdType = type;
				_steamIdField = AccessTools.Field(type, "steamID");
			}
			return (_steamIdField?.GetValue(obj) as string) ?? string.Empty;
		}

		private static void InvokeMenu(object menu, MethodInfo? method, int index)
		{
			if (method == null)
			{
				return;
			}
			try
			{
				method.Invoke(menu, new object[1] { index });
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[BiggerLobby] 调用 " + method.Name + " 失败:" + (ex.InnerException?.Message ?? ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(SteamMatchmaking), "CreateLobby")]
	internal static class CreateLobbyPatch
	{
		private static void Prefix(ref int cMaxMembers)
		{
			if (ModPreferences.Enabled)
			{
				cMaxMembers = ModPreferences.MaxPlayers;
				MelonLogger.Msg($"[BiggerLobby] Steam 大厅人数上限 = {cMaxMembers}");
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class MaxPlayerCountPatch
	{
		private static readonly FieldInfo? MaxField = AccessTools.Field(typeof(DataConsts), "C_MaxPlayerCount");

		private static void Postfix(DataConsts __instance)
		{
			if (!ModPreferences.Enabled || MaxField == null)
			{
				return;
			}
			try
			{
				MaxField.SetValue(__instance, ModPreferences.MaxPlayers);
				MelonLogger.Msg($"[BiggerLobby] 游戏内人数上限 C_MaxPlayerCount = {MaxField.GetValue(__instance)}");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[BiggerLobby] 写入 C_MaxPlayerCount 失败:{arg}");
			}
		}
	}
	[HarmonyPatch(typeof(UIPrefab_Spectator_PlayerListView), "Start")]
	internal static class SpectatorListStartPatch
	{
		internal const int UiSlots = 16;

		private static readonly FieldInfo? ItemsField = AccessTools.Field(typeof(UIPrefab_Spectator_PlayerListView), "playerListViewItems");

		private static void Postfix(UIPrefab_Spectator_PlayerListView __instance)
		{
			if (!ModPreferences.Enabled)
			{
				return;
			}
			try
			{
				Expand(__instance);
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[BiggerLobby] 观战列表扩展失败:{arg}");
			}
		}

		internal static UIPrefab_Spectator_PlayerListViewItem[]? GetItems(UIPrefab_Spectator_PlayerListView listView)
		{
			return ItemsField?.GetValue(listView) as UIPrefab_Spectator_PlayerListViewItem[];
		}

		private static void Expand(UIPrefab_Spectator_PlayerListView listView)
		{
			if (!(ItemsField?.GetValue(listView) is UIPrefab_Spectator_PlayerListViewItem[] array) || array.Length == 0 || array.Length >= 16)
			{
				return;
			}
			UIPrefab_Spectator_PlayerListViewItem val = array[^1];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform parent = ((Component)val).transform.parent;
			List<UIPrefab_Spectator_PlayerListViewItem> list = new List<UIPrefab_Spectator_PlayerListViewItem>(array);
			while (list.Count < 16)
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)obj).name = ((Object)((Component)val).gameObject).name + "_" + (list.Count + 1);
				obj.SetActive(true);
				UIPrefab_Spectator_PlayerListViewItem component = obj.GetComponent<UIPrefab_Spectator_PlayerListViewItem>();
				if ((Object)(object)component == (Object)null)
				{
					MelonLogger.Warning("[BiggerLobby] 克隆观战列表项失败。");
					break;
				}
				component.SetDead(false);
				component.Clear();
				list.Add(component);
			}
			ItemsField.SetValue(listView, list.ToArray());
			MelonLogger.Msg($"[BiggerLobby] 观战列表行数:{array.Length} -> {list.Count}");
		}
	}
	[HarmonyPatch(typeof(UIPrefab_Spectator_PlayerListView), "UpdatePlayerListView")]
	internal static class SpectatorListUpdatePatch
	{
		private static void Postfix(UIPrefab_Spectator_PlayerListView __instance, object[] __args)
		{
			if (!ModPreferences.Enabled)
			{
				return;
			}
			try
			{
				UIPrefab_Spectator_PlayerListViewItem[] items = SpectatorListStartPatch.GetItems(__instance);
				if (items == null || items.Length == 0)
				{
					return;
				}
				int num = 0;
				if (__args != null && __args.Length != 0 && __args[0] is IList list)
				{
					num = list.Count;
				}
				int num2 = Mathf.Clamp(num, 0, items.Length);
				if (ModPreferences.DebugPlaceholders)
				{
					for (int i = num; i < items.Length; i++)
					{
						UIPrefab_Spectator_PlayerListViewItem obj = items[i];
						if (obj != null)
						{
							obj.SetName($"PLAYER {i + 1:D2}");
						}
					}
					num2 = Mathf.Min(items.Length, Mathf.Min(ModPreferences.MaxPlayers, 16));
				}
				if (num2 > 0)
				{
					ScheduleLayout(items, num2);
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[BiggerLobby] 观战列表排布失败:{arg}");
			}
		}

		private static void ScheduleLayout(UIPrefab_Spectator_PlayerListViewItem[] items, int visible)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(((Object)(object)items[0] != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			RectTransform val2 = (RectTransform)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return;
			}
			Rect rect = val.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			if (size.x < 1f || size.y < 1f)
			{
				((Vector2)(ref size))..ctor(240f, 56f);
			}
			int columns = Mathf.Clamp(ModPreferences.SpectatorColumns, 1, 8);
			List<RectTransform> items2 = ((IEnumerable<UIPrefab_Spectator_PlayerListViewItem>)items).Select((Func<UIPrefab_Spectator_PlayerListViewItem, RectTransform>)delegate(UIPrefab_Spectator_PlayerListViewItem item)
			{
				if (!((Object)(object)item != (Object)null))
				{
					return (RectTransform)null;
				}
				Transform transform = ((Component)item).transform;
				return (RectTransform)(object)((transform is RectTransform) ? transform : null);
			}).ToList();
			UiGridLayout.Schedule(val2, items2, visible, size, columns, ModPreferences.SpectatorScale, val2, ModPreferences.SpectatorOffsetY, ModPreferences.SpectatorOffsetX, ModPreferences.SpectatorFillByColumn);
		}
	}
	[HarmonyPatch(typeof(UIPrefab_Spectator), "SetSpectatedPlayerName")]
	internal static class SpectatorNamePatch
	{
		private static void Postfix(UIPrefab_Spectator __instance)
		{
			if (!ModPreferences.Enabled || !ModPreferences.ShowFullSpectatorName)
			{
				return;
			}
			try
			{
				Fit(__instance);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[BiggerLobby] 观战名字自适应失败:" + ex.Message);
			}
		}

		private static void Fit(UIPrefab_Spectator spectator)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_00fa: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text uE_UI_NameText = spectator.UE_UI_NameText;
			if ((Object)(object)uE_UI_NameText == (Object)null)
			{
				return;
			}
			uE_UI_NameText.overflowMode = (TextOverflowModes)0;
			uE_UI_NameText.textWrappingMode = (TextWrappingModes)0;
			uE_UI_NameText.enableAutoSizing = false;
			uE_UI_NameText.maxVisibleCharacters = 99999;
			uE_UI_NameText.firstVisibleCharacter = 0;
			RectTransform rectTransform = uE_UI_NameText.rectTransform;
			float x = uE_UI_NameText.GetPreferredValues(uE_UI_NameText.text).x;
			Rect rect = rectTransform.rect;
			float width = ((Rect)(ref rect)).width;
			if (x > width)
			{
				Canvas componentInParent = ((Component)uE_UI_NameText).GetComponentInParent<Canvas>();
				float num = 1800f;
				if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.rootCanvas != (Object)null)
				{
					rect = ((RectTransform)((Component)componentInParent.rootCanvas).transform).rect;
					num = ((Rect)(ref rect)).width * 0.95f;
				}
				rectTransform.SetSizeWithCurrentAnchors((Axis)0, Mathf.Min(x + 16f, num));
			}
			RectMask2D componentInParent2 = ((Component)uE_UI_NameText).GetComponentInParent<RectMask2D>();
			object[] obj = new object[4] { uE_UI_NameText.text, x, width, null };
			rect = rectTransform.rect;
			obj[3] = ((Rect)(ref rect)).width;
			ModPreferences.Log(string.Format("[BiggerLobby] 观战名字 '{0}':需要 {1:0.#},原宽 {2:0.#} -> {3:0.#},", obj) + "mask=" + (((Object)(object)componentInParent2 != (Object)null) ? ((Object)componentInParent2).name : "none"));
		}
	}
	[HarmonyPatch]
	internal static class SurvivalResultPatch
	{
		internal const int UiSlots = 16;

		private const string GridName = "BiggerLobbyResultGrid";

		private static Type? _type;

		private static FieldInfo? _columnsField;

		private static FieldInfo? _countField;

		private static MethodInfo? _patchResult;

		private static readonly Dictionary<int, List<UIPrefab_SurvivalResultPlayerColumn>> ExtraColumns = new Dictionary<int, List<UIPrefab_SurvivalResultPlayerColumn>>();

		private static object? _lastInstance;

		private static UIPrefab_SurvivalResultPlayerColumn[]? _lastColumns;

		private static RectTransform? _lastArea;

		private static int _lastVisible;

		private static float _lastTopOffset;

		private static object? _offsetInstance;

		private static float _autoTopOffset;

		private static MethodBase? TargetMethod()
		{
			_type = AccessTools.TypeByName("UIPrefab_SurvivalResult");
			if (_type == null)
			{
				MelonLogger.Error("[BiggerLobby] 找不到类型 UIPrefab_SurvivalResult,结算界面补丁未应用。");
				return null;
			}
			_columnsField = AccessTools.Field(_type, "_playerColumns");
			_countField = AccessTools.Field(_type, "_resultCount");
			_patchResult = AccessTools.Method(typeof(UIPrefab_SurvivalResultPlayerColumn), "PatchResult", (Type[])null, (Type[])null);
			MethodInfo methodInfo = AccessTools.Method(_type, "PatchParameter", (Type[])null, (Type[])null);
			MelonLogger.Msg("[BiggerLobby] 结算补丁目标:" + _type.FullName + ".PatchParameter -> " + ((methodInfo == null) ? "null" : "ok") + ", columnsField=" + ((_columnsField == null) ? "null" : "ok") + ", patchResult=" + ((_patchResult == null) ? "null" : "ok"));
			return methodInfo;
		}

		internal static object[]? BuildDebugParameters(int slots)
		{
			if (_type == null)
			{
				return null;
			}
			Type nestedType = _type.GetNestedType("eActorSurvivalState", BindingFlags.Public | BindingFlags.NonPublic);
			if (nestedType == null)
			{
				return null;
			}
			List<object> list = new List<object> { 1, 1, true, slots };
			for (int i = 0; i < slots; i++)
			{
				list.Add($"PLAYER {i + 1:D2}");
				list.Add(Enum.ToObject(nestedType, i % 3));
				list.Add((object)(AwardType)0);
			}
			list.Add(0);
			return list.ToArray();
		}

		private static void Postfix(object __instance, object[] __args)
		{
			if (!ModPreferences.Enabled || __args == null || __args.Length == 0 || !(__args[0] is object[] array) || array.Length < 4)
			{
				return;
			}
			try
			{
				Apply(__instance, array);
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[BiggerLobby] 结算界面扩展失败:{arg}");
			}
		}

		internal static void OnShown(object instance)
		{
			if (ModPreferences.Enabled && instance == _lastInstance && _lastColumns != null && (Object)(object)_lastArea != (Object)null && _lastVisible > 0)
			{
				ScheduleLayout(_lastArea, _lastColumns, _lastVisible, _lastTopOffset);
			}
		}

		private static void Apply(object instance, object[] parameters)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			if (_columnsField == null)
			{
				MelonLogger.Warning("[BiggerLobby] _playerColumns 字段未解析,跳过结算扩展。");
				return;
			}
			if (!(_columnsField.GetValue(instance) is UIPrefab_SurvivalResultPlayerColumn[] array) || array.Length == 0)
			{
				MelonLogger.Warning("[BiggerLobby] 结算列数组为空,跳过结算扩展。");
				return;
			}
			int num = Mathf.Min(ModPreferences.MaxPlayers, 16);
			int num2 = (int)parameters[3];
			if (num2 > num)
			{
				MelonLogger.Warning($"[BiggerLobby] 结算玩家数 {num2} 超过界面上限 {num},只显示前 {num} 个。");
				num2 = num;
			}
			int num3 = (ModPreferences.DebugPlaceholders ? num : Mathf.Min(num2, num));
			if (num3 <= 4)
			{
				ModPreferences.Log($"[BiggerLobby] 结算玩家数 {num3} <= 4,保持原版排版。");
				return;
			}
			object obj = ((instance is Component) ? instance : null);
			Transform obj2 = ((obj != null) ? ((Component)obj).transform : null);
			RectTransform root = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
			Vector2 val = MeasureNatural(array);
			if (_offsetInstance != instance)
			{
				_autoTopOffset = ComputeAutoTopOffset(root, array);
				_offsetInstance = instance;
				ModPreferences.Log($"[BiggerLobby] 原版结算列顶部偏移 = {_autoTopOffset:0.#}px");
			}
			float num4 = _autoTopOffset + ModPreferences.ResultTopOffset;
			object obj3 = ((instance is Component) ? instance : null);
			UIPrefab_SurvivalResultPlayerColumn[] array2 = EnsureColumns(array, num, (obj3 != null) ? ((Object)obj3).GetInstanceID() : 0);
			_columnsField.SetValue(instance, array2);
			RectTransform val2 = EnsureGridRoot(instance, array2);
			if ((Object)(object)val2 == (Object)null)
			{
				MelonLogger.Warning("[BiggerLobby] 无法创建结算网格容器,退回原容器排布。");
			}
			Type stateType = ((_patchResult != null) ? _patchResult.GetParameters()[1].ParameterType : null);
			for (int i = 0; i < array2.Length; i++)
			{
				UIPrefab_SurvivalResultPlayerColumn val3 = array2[i];
				if (!((Object)(object)val3 == (Object)null))
				{
					if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val3).transform.parent != (Object)(object)val2)
					{
						((Component)val3).transform.SetParent((Transform)(object)val2, false);
					}
					if (i < num2)
					{
						string name = parameters[3 * i + 4]?.ToString() ?? string.Empty;
						int state = (int)parameters[3 * i + 5];
						object award = parameters[3 * i + 6] ?? ((object)(AwardType)0);
						PatchColumn(val3, name, stateType, state, award);
						((Component)val3).gameObject.SetActive(true);
					}
					else if (ModPreferences.DebugPlaceholders && i < num)
					{
						PatchColumn(val3, $"PLAYER {i + 1:D2}", stateType, 0, (object)(AwardType)0);
						((Component)val3).gameObject.SetActive(true);
					}
					else
					{
						((Component)val3).gameObject.SetActive(false);
					}
				}
			}
			_countField?.SetValue(instance, num3);
			_lastInstance = instance;
			_lastColumns = array2;
			_lastArea = (RectTransform?)(((Object)(object)val2 != (Object)null) ? ((object)val2) : ((object)/*isinst with value type is only supported in some contexts*/));
			_lastVisible = num3;
			_lastTopOffset = num4;
			MelonLogger.Msg($"[BiggerLobby] 结算界面:playerCount={num2}, 列={array2.Length}, 显示={num3}, " + string.Format("容器={0}, 单元={1}, 顶部偏移={2:0.#}px ", ((Object)(object)_lastArea != (Object)null) ? ((Object)_lastArea).name : "null", val, num4) + $"(原版 {_autoTopOffset:0.#} + 配置 {ModPreferences.ResultTopOffset:0.#})");
			if ((Object)(object)_lastArea != (Object)null)
			{
				ScheduleLayout(_lastArea, array2, num3, num4);
			}
		}

		private static Vector2 MeasureNatural(UIPrefab_SurvivalResultPlayerColumn[] columns)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(((Object)(object)columns[0] != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			Vector2 val2;
			if (!((Object)(object)val != (Object)null))
			{
				val2 = Vector2.zero;
			}
			else
			{
				Rect rect = val.rect;
				val2 = ((Rect)(ref rect)).size;
			}
			Vector2 val3 = val2;
			if (val3.x < 1f || val3.y < 1f)
			{
				((Vector2)(ref val3))..ctor(200f, 240f);
			}
			return val3;
		}

		private static float ComputeAutoTopOffset(RectTransform? root, UIPrefab_SurvivalResultPlayerColumn[] columns)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return 0f;
			}
			float num = float.MinValue;
			Rect rect;
			foreach (UIPrefab_SurvivalResultPlayerColumn val in columns)
			{
				RectTransform val2 = (RectTransform)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
				if (!((Object)(object)val2 == (Object)null))
				{
					rect = val2.rect;
					Vector3 val3 = ((Transform)val2).TransformPoint(new Vector3(0f, ((Rect)(ref rect)).yMax, 0f));
					Vector3 val4 = ((Transform)root).InverseTransformPoint(val3);
					if (val4.y > num)
					{
						num = val4.y;
					}
				}
			}
			if (num == float.MinValue)
			{
				return 0f;
			}
			rect = root.rect;
			float num2 = ((Rect)(ref rect)).yMax - num;
			rect = root.rect;
			return Mathf.Clamp(num2, 0f, Mathf.Max(0f, ((Rect)(ref rect)).height));
		}

		private static RectTransform? EnsureGridRoot(object instance, UIPrefab_SurvivalResultPlayerColumn[] columns)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			object obj = ((instance is Component) ? instance : null);
			Transform obj2 = ((obj != null) ? ((Component)obj).transform : null);
			RectTransform val = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
			if ((Object)(object)val == (Object)null)
			{
				if (!((Object)(object)columns[0] != (Object)null))
				{
					return null;
				}
				Transform parent = ((Component)columns[0]).transform.parent;
				return (RectTransform?)(object)((parent is RectTransform) ? parent : null);
			}
			Transform obj3 = ((Transform)val).Find("BiggerLobbyResultGrid");
			RectTransform val2 = (RectTransform)(object)((obj3 is RectTransform) ? obj3 : null);
			if (val2 != null)
			{
				return val2;
			}
			GameObject val3 = new GameObject("BiggerLobbyResultGrid", new Type[1] { typeof(RectTransform) });
			RectTransform val4 = (RectTransform)val3.transform;
			((Transform)val4).SetParent((Transform)(object)val, false);
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			((Transform)val4).SetAsLastSibling();
			val3.AddComponent<LayoutElement>().ignoreLayout = true;
			string name = ((Object)val).name;
			Rect rect = val.rect;
			ModPreferences.Log($"[BiggerLobby] 创建结算网格容器,root='{name}' rect={((Rect)(ref rect)).size}");
			return val4;
		}

		private static UIPrefab_SurvivalResultPlayerColumn[] EnsureColumns(UIPrefab_SurvivalResultPlayerColumn[] columns, int slots, int key)
		{
			if (columns.Length >= slots)
			{
				return columns;
			}
			UIPrefab_SurvivalResultPlayerColumn val = columns[^1];
			if ((Object)(object)val == (Object)null)
			{
				return columns;
			}
			Transform parent = ((Component)val).transform.parent;
			if (!ExtraColumns.TryGetValue(key, out List<UIPrefab_SurvivalResultPlayerColumn> value) || value == null)
			{
				value = new List<UIPrefab_SurvivalResultPlayerColumn>();
				ExtraColumns[key] = value;
			}
			value.RemoveAll((UIPrefab_SurvivalResultPlayerColumn column) => (Object)(object)column == (Object)null);
			while (columns.Length + value.Count < slots)
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)obj).name = ((Object)((Component)val).gameObject).name + "_" + (columns.Length + value.Count + 1);
				obj.SetActive(false);
				UIPrefab_SurvivalResultPlayerColumn component = obj.GetComponent<UIPrefab_SurvivalResultPlayerColumn>();
				if ((Object)(object)component == (Object)null)
				{
					MelonLogger.Warning("[BiggerLobby] 克隆结算列失败:缺少 UIPrefab_SurvivalResultPlayerColumn。");
					break;
				}
				value.Add(component);
			}
			List<UIPrefab_SurvivalResultPlayerColumn> list = new List<UIPrefab_SurvivalResultPlayerColumn>(slots);
			list.AddRange(columns);
			list.AddRange(value.GetRange(0, Mathf.Max(0, Mathf.Min(value.Count, slots - columns.Length))));
			return list.ToArray();
		}

		private static void PatchColumn(UIPrefab_SurvivalResultPlayerColumn column, string name, Type? stateType, int state, object award)
		{
			if (_patchResult == null || stateType == null)
			{
				return;
			}
			try
			{
				_patchResult.Invoke(column, new object[3]
				{
					name,
					Enum.ToObject(stateType, state),
					award
				});
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[BiggerLobby] 写入结算列失败:" + (ex.InnerException?.Message ?? ex.Message));
			}
		}

		private static void ScheduleLayout(RectTransform area, UIPrefab_SurvivalResultPlayerColumn[] columns, int visible, float topOffset)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			if (visible <= 4)
			{
				UiUtil.RestoreLayout(area);
				return;
			}
			int columns2 = Mathf.Clamp(Mathf.Min(ModPreferences.ResultColumns, visible), 1, 8);
			Vector2 natural = MeasureNatural(columns);
			List<RectTransform> items = ((IEnumerable<UIPrefab_SurvivalResultPlayerColumn>)columns).Select((Func<UIPrefab_SurvivalResultPlayerColumn, RectTransform>)delegate(UIPrefab_SurvivalResultPlayerColumn column)
			{
				if (!((Object)(object)column != (Object)null))
				{
					return (RectTransform)null;
				}
				Transform transform = ((Component)column).transform;
				return (RectTransform)(object)((transform is RectTransform) ? transform : null);
			}).ToList();
			UiGridLayout.Schedule(area, items, visible, natural, columns2, ModPreferences.ResultScale, area, topOffset);
		}
	}
	[HarmonyPatch]
	internal static class SurvivalResultShowPatch
	{
		private static MethodBase? TargetMethod()
		{
			Type type = AccessTools.TypeByName("UIPrefab_SurvivalResult");
			if (!(type == null))
			{
				return AccessTools.Method(type, "OnShow", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static void Postfix(object __instance)
		{
			SurvivalResultPatch.OnShown(__instance);
		}
	}
}