Decompiled source of ResonatorsOfTheSoul v0.25.33

ResonatorsOfTheSoul.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Drifter;
using EntityStates.FalseSon;
using EntityStates.LunarTeleporter;
using EntityStates.Seeker;
using HG;
using HurricaneDifficulty.Config;
using HurricaneDifficulty.Pantheon;
using IL;
using IL.EntityStates;
using IL.EntityStates.Bell.BellWeapon;
using IL.EntityStates.FalseSon;
using IL.EntityStates.FlyingVermin.Weapon;
using IL.EntityStates.SolusHeart.Death;
using IL.RoR2;
using IL.RoR2.Artifacts;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using On.EntityStates.Drifter;
using On.EntityStates.Seeker;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.UI;
using On.RoR2.UI.MainMenu;
using PvPMode;
using PvPMode.Combat;
using PvPMode.Compatibility;
using PvPMode.Config;
using PvPMode.Debugging;
using PvPMode.Equipment;
using PvPMode.Loadouts;
using PvPMode.Match;
using PvPMode.Minions;
using PvPMode.Respawn;
using PvPMode.Routes;
using PvPMode.Spawn;
using PvPMode.Teams;
using PvPMode.UI;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Achievements;
using RoR2.AddressableAssets;
using RoR2.CharacterAI;
using RoR2.ExpansionManagement;
using RoR2.HudOverlay;
using RoR2.Items;
using RoR2.Navigation;
using RoR2.Networking;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.Stats;
using RoR2.UI;
using RoR2.UI.LogBook;
using RoR2.UI.MainMenu;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
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("ResonatorsOfTheSoul")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.25.33.0")]
[assembly: AssemblyInformationalVersion("0.25.33")]
[assembly: AssemblyProduct("ResonatorsOfTheSoul")]
[assembly: AssemblyTitle("ResonatorsOfTheSoul")]
[assembly: AssemblyVersion("0.25.33.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 PvPMode
{
	public static class Plugin
	{
		internal const string GameModePrefabName = "WaterBucketPvPModeRun";

		internal const string GameModeNameToken = "WATERBUCKET_PVP_MODE_NAME";

		internal const string GameModeDescriptionToken = "WATERBUCKET_PVP_MODE_DESCRIPTION";

		private static bool initialized;

		internal static BaseUnityPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static GameEndingDef? PvPMatchEnding { get; private set; }

		public static bool IsPvPModeActive
		{
			get
			{
				if (ResonatorModules.PvPActive && Object.op_Implicit((Object)(object)Run.instance))
				{
					return Object.op_Implicit((Object)(object)((Component)Run.instance).GetComponent<PvPModeRunMarker>());
				}
				return false;
			}
		}

		internal static void Initialize(BaseUnityPlugin owner, ManualLogSource logger)
		{
			if (!initialized)
			{
				initialized = true;
				Instance = owner;
				Log = logger;
				PvPConfig.Bind(owner.Config);
				RegisterLanguage();
				PvPTeamRegistry.RegisterTeams(PvPConfig.MaxPvPTeams.Value);
				RegisterGameMode();
				RegisterMatchEnding();
				PvPTeamManager.Install();
				PvPMatchManager.Install();
				VanillaPlayerTeamCompatibility.Install();
				PvPSurvivorMechanics.Install();
				PvPMinionTeamController.Install();
				PvPDamageController.Install();
				PvPSpawnManager.Install();
				PvPRespawnManager.Install();
				PvPStageRouteManager.Install();
				PvPStartingLoadoutManager.Install();
				PvPRadarScannerNames.Install();
				PvPScoreboardPrivacy.Install();
				PvPLobbySettingsUI.Install();
				PvPCommands.Install();
				Log.LogInfo((object)"Resonators of the Soul PvP module initialized.");
			}
		}

		internal static void Shutdown()
		{
			if (initialized)
			{
				initialized = false;
				PvPCommands.Uninstall();
				PvPLobbySettingsUI.Uninstall();
				PvPScoreboardPrivacy.Uninstall();
				PvPRadarScannerNames.Uninstall();
				PvPStartingLoadoutManager.Uninstall();
				PvPStageRouteManager.Uninstall();
				PvPRespawnManager.Uninstall();
				PvPSpawnManager.Uninstall();
				PvPDamageController.Uninstall();
				PvPMinionTeamController.Uninstall();
				PvPSurvivorMechanics.Uninstall();
				VanillaPlayerTeamCompatibility.Uninstall();
				PvPMatchManager.Uninstall();
				PvPTeamManager.Uninstall();
				PvPMatchEnding = null;
			}
		}

		private static void RegisterLanguage()
		{
			LanguageAPI.Add("WATERBUCKET_PVP_MODE_NAME", "PvP Mode");
			LanguageAPI.Add("WATERBUCKET_PVP_MODE_NAME", "PvP 对战", "zh-CN");
			LanguageAPI.Add("WATERBUCKET_PVP_MODE_DESCRIPTION", "Rival player teams with scaled PvP damage, separated spawns, minion allegiance, and respawning.");
			LanguageAPI.Add("WATERBUCKET_PVP_MODE_DESCRIPTION", "玩家分属敌对队伍,具有独立 PvP 伤害倍率、分散出生、召唤物阵营继承和死亡重生。", "zh-CN");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_BUTTON", "PvP Settings", "PvP 设置");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TITLE", "PvP Lobby Settings", "PvP 房间设置");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_HINT", "Host settings are saved immediately and apply when the run starts.", "仅房主可修改;设置会立即保存,并在开局时生效。");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_RULES", "RULES", "规则");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_MODE", "MODE", "模式");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_TEAMS", "TEAMS", "分队");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_LOADOUT", "LOADOUT", "装备");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MODE_HINT", "Choose the match ending rule, team structure, and respawn behavior.", "设置比赛结束条件、队伍结构和复活规则。");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_HOST_ONLY", "Only the host can edit match rules.", "仅房主可修改对战规则。");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_MATCH", "MATCH", "对战");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_MATCH_RULE", "MATCH RULE", "胜负规则");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_TEAMS", "TEAMS", "队伍");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_SPAWN", "SPAWNING", "出生");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_RESPAWN", "RESPAWNING", "复活");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_ROUTE", "STAGE ROUTE", "关卡路线");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_HINT", "Choose your own team. Automatic players still follow the host's assignment rule.", "选择你要加入的队伍;选择自动的玩家仍按房主设定的规则分配。");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_AUTO", "Automatic", "自动分配");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_CURRENT", "Current choice", "当前选择");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_ROSTER", "LOBBY PLAYERS", "房间玩家");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_PENDING", "Automatic / pending", "自动 / 待分配");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_HINT", "The host sets per-player allowances. Every player chooses only their own starting items.", "房主设置每人额度;每名玩家只能选择自己的初始物品。");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_CATEGORY", "Item category", "物品类别");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_ALLOWANCE", "Per-player allowance", "每人额度");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_SELECTED", "Selected: {0} / {1}", "已选择:{0} / {1}");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_CLICK_HINT", "Left click to add; right click to remove. Lunar equipment uses blue allowance.", "左键增加,右键减少;月球主动装备占用蓝色额度。");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_CLEAR", "Clear this category", "清空当前类别");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_WHITE", "White", "白色");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_GREEN", "Green", "绿色");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_YELLOW", "Yellow", "黄色");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_ORANGE", "Orange equipment", "橙色主动装备");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_RED", "Red", "红色");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_BLUE", "Blue / Lunar", "蓝色/月球");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_VOID_WHITE", "Void white", "白紫");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_VOID_GREEN", "Void green", "绿紫");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_VOID_RED", "Void red", "红紫");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESETS", "LOCAL PRESETS", "本地配装预设");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_HINT", "Left click a slot to load it; right click to overwrite-save the current full loadout.", "左键一键加载;右键用当前完整配装覆盖保存。");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_SAVED", "◆ Preset {0}", "◆ 预设 {0}");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_EMPTY", "Preset {0}", "预设 {0}");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_SAVED", "Saved preset {0} ({1} selections).", "已保存预设 {0}({1} 件)。");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_LOADED", "Loaded preset {0}: {1} selected, {2} skipped.", "已加载预设 {0}:选择 {1} 件,跳过 {2} 件。");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_EMPTY", "This preset slot is empty.", "这个预设栏位为空。");
			AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_INVALID", "This preset could not be read.", "这个预设无法读取。");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_MODE", "Match mode", "比赛模式");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_LIMITED", "Limited lives", "有限生命");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_UNLIMITED", "Unlimited", "无限制");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_TIMED", "Timed team kills", "限时队伍击杀");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_LIVES", "Lives per player", "每人生命数");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TIME_LIMIT", "Time limit", "时间限制");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_CLOSE", "Close", "关闭");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_ENABLED", "Enabled", "开启");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_DISABLED", "Disabled", "关闭");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_MODE", "Teams", "组队");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MODE", "Team assignment", "队伍模式");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_COUNT", "Team count", "队伍数量");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_FRIENDLY_FIRE", "Friendly fire", "队友伤害");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_PLAYER_PLAYER", "Player → player damage", "玩家 → 玩家伤害");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MINION_PLAYER", "Minion → player damage", "召唤物 → 玩家伤害");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_PLAYER_MINION", "Player → minion damage", "玩家 → 召唤物伤害");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_MINION_MINION", "Minion → minion damage", "召唤物 → 召唤物伤害");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_CONTROL_DURATION", "Player hard-control duration", "玩家硬控时间倍率");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_FALLBACK_DISTANCE", "Fallback spawn distance", "备用出生距离");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_RADIUS", "Ally spawn radius", "队友出生半径");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_SPAWN_PROTECTION", "Initial spawn protection", "初始出生保护");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_RESPAWN", "Automatic respawn", "自动复活");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_RESPAWN_DELAY", "Respawn delay", "复活等待时间");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_RESPAWN_PROTECTION", "Respawn protection", "复活保护");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_STAGE_FIVE_ROUTE", "Sky Meadow default route", "第五层默认路线");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_ROUTE_LOOP", "Loop", "循环");
			AddLanguage("WATERBUCKET_PVP_SETTINGS_ROUTE_MOON", "Moon", "月球");
			AddLanguage("WATERBUCKET_PVP_MATCH_ENDING", "PvP match complete", "PvP 对战结束");
			AddLanguage("WATERBUCKET_PVP_MATCH_START_LIVES", "Limited-lives match started: {0} lives per player.", "有限生命比赛开始:每名玩家 {0} 条生命。");
			AddLanguage("WATERBUCKET_PVP_MATCH_START_UNLIMITED", "Unlimited PvP match started. There is no automatic ending condition.", "无限制比赛开始:不会自动结束。");
			AddLanguage("WATERBUCKET_PVP_MATCH_START_TIMED", "Timed team-kill match started: {0} minutes.", "限时队伍击杀比赛开始:限时 {0} 分钟。");
			AddLanguage("WATERBUCKET_PVP_MATCH_LIVES_MESSAGE", "{0} has {1} lives remaining.", "{0} 剩余 {1} 条生命。");
			AddLanguage("WATERBUCKET_PVP_MATCH_SEEKER_LIFE", "Seeker revived eliminated player {0} and restored 1 life.", "求道者复活了已淘汰玩家 {0},并为其恢复 1 条生命。");
			AddLanguage("WATERBUCKET_PVP_MATCH_SCORE_MESSAGE", "{0} now has {1} kills.", "{0} 当前击杀数:{1}。");
			AddLanguage("WATERBUCKET_PVP_MATCH_OVERTIME", "The score is tied. Overtime continues until there is a sole leading team.", "最高击杀数相同,进入加时;出现唯一领先队伍时结束。");
			AddLanguage("WATERBUCKET_PVP_MATCH_WINNER", "{0} wins the PvP match!", "{0} 赢得了 PvP 比赛!");
			AddLanguage("WATERBUCKET_PVP_MATCH_NO_VIABLE_TEAMS", "No team has any lives remaining.", "所有队伍的生命均已耗尽。");
			AddLanguage("WATERBUCKET_PVP_RESPAWN_COUNTDOWN", "Respawning in {0}s  •  {1} lives remaining", "将在 {0} 秒后复活\u3000•\u3000剩余 {1} 条生命");
			AddLanguage("WATERBUCKET_PVP_RESPAWN_NOW", "Respawning…  •  {0} lives remaining", "正在复活…\u3000•\u3000剩余 {0} 条生命");
			for (int i = 0; i < PvPConfig.MaxPvPTeams.Value; i++)
			{
				string teamNameToken = PvPTeamRegistry.GetTeamNameToken(i);
				LanguageAPI.Add(teamNameToken, $"PvP Team {i + 1}");
				LanguageAPI.Add(teamNameToken, $"PvP 队伍 {i + 1}", "zh-CN");
			}
		}

		private static void AddLanguage(string token, string english, string simplifiedChinese)
		{
			LanguageAPI.Add(token, english);
			LanguageAPI.Add(token, simplifiedChinese, "zh-CN");
		}

		private static void RegisterGameMode()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/ClassicRun/ClassicRun.prefab").WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidOperationException("Could not load the current ClassicRun prefab.");
			}
			GameObject obj2 = PrefabAPI.InstantiateClone(obj, "WaterBucketPvPModeRun", true);
			Run component = obj2.GetComponent<Run>();
			component.nameToken = "WATERBUCKET_PVP_MODE_NAME";
			component.userPickable = true;
			obj2.AddComponent<PvPModeRunMarker>();
			if (!ContentAddition.AddGameMode(obj2, "WATERBUCKET_PVP_MODE_DESCRIPTION"))
			{
				throw new InvalidOperationException("R2API rejected the PvP game-mode prefab.");
			}
		}

		private static void RegisterMatchEnding()
		{
			//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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameEndingDef val = ScriptableObject.CreateInstance<GameEndingDef>();
				((Object)val).name = "WaterBucketPvPMatchEnding";
				val.cachedName = "WaterBucketPvPMatchEnding";
				val.endingTextToken = "WATERBUCKET_PVP_MATCH_ENDING";
				val.isWin = true;
				val.showCredits = false;
				val.lunarCoinReward = 0u;
				val.defaultKillerOverride = null;
				val.backgroundColor = new Color(0.035f, 0.055f, 0.09f, 1f);
				val.foregroundColor = new Color(0.55f, 0.85f, 1f, 1f);
				if (ContentAddition.AddGameEndingDef(val))
				{
					PvPMatchEnding = val;
					return;
				}
				Object.Destroy((Object)(object)val);
				Log.LogWarning((object)"R2API rejected the custom PvP ending. A vanilla ending will be used instead.");
			}
			catch (Exception arg)
			{
				PvPMatchEnding = null;
				Log.LogWarning((object)$"Could not register the custom PvP ending; PvP mode remains available. {arg}");
			}
		}

		internal static GameEndingDef? GetMatchEnding()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameEndingDef pvPMatchEnding = PvPMatchEnding;
			GameEndingDef val = GameEndings.PrismaticTrialEnding;
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = GameEndings.StandardLoss;
			}
			if (pvPMatchEnding != null && Object.op_Implicit((Object)(object)pvPMatchEnding) && val != null && Object.op_Implicit((Object)(object)val))
			{
				pvPMatchEnding.gameOverControllerState = val.gameOverControllerState;
				pvPMatchEnding.icon = val.icon;
				pvPMatchEnding.material = val.material;
				return pvPMatchEnding;
			}
			return val;
		}

		internal static GameEndingDef? GetLossEnding()
		{
			GameEndingDef standardLoss = GameEndings.StandardLoss;
			if (standardLoss == null || !Object.op_Implicit((Object)(object)standardLoss))
			{
				return GetMatchEnding();
			}
			return standardLoss;
		}
	}
	public sealed class PvPModeRunMarker : MonoBehaviour
	{
	}
}
namespace PvPMode.UI
{
	internal static class PvPLobbySettingsUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__CharacterSelectControllerAwake;
		}

		private static bool installed;

		internal static void Install()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (!installed)
			{
				installed = true;
				object obj = <>O.<0>__CharacterSelectControllerAwake;
				if (obj == null)
				{
					hook_Awake val = CharacterSelectControllerAwake;
					<>O.<0>__CharacterSelectControllerAwake = val;
					obj = (object)val;
				}
				CharacterSelectController.Awake += (hook_Awake)obj;
			}
		}

		internal static void Uninstall()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (installed)
			{
				installed = false;
				object obj = <>O.<0>__CharacterSelectControllerAwake;
				if (obj == null)
				{
					hook_Awake val = CharacterSelectControllerAwake;
					<>O.<0>__CharacterSelectControllerAwake = val;
					obj = (object)val;
				}
				CharacterSelectController.Awake -= (hook_Awake)obj;
			}
		}

		private static void CharacterSelectControllerAwake(orig_Awake orig, CharacterSelectController self)
		{
			orig.Invoke(self);
			if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<PvPLobbySettingsPanel>()))
			{
				((Component)self).gameObject.AddComponent<PvPLobbySettingsPanel>();
			}
		}
	}
	internal sealed class PvPLobbySettingsPanel : MonoBehaviour
	{
		private const int ModulesPage = 0;

		private const int ModePage = 1;

		private const int RulesPage = 2;

		private const int TeamsPage = 3;

		private const int LoadoutPage = 4;

		private const string SettingsTitle = "Resonators of the Soul 设置";

		private const string CloseToken = "WATERBUCKET_PVP_SETTINGS_CLOSE";

		private readonly List<Action> valueRefreshers = new List<Action>();

		private readonly List<(MPButton Button, int TeamId)> teamButtons = new List<(MPButton, int)>();

		private readonly List<(MPButton Button, StartingLoadoutOption Option, TMP_Text Label)> loadoutButtons = new List<(MPButton, StartingLoadoutOption, TMP_Text)>();

		private readonly List<(MPButton Button, TMP_Text Label, int SlotIndex)> loadoutPresetButtons = new List<(MPButton, TMP_Text, int)>();

		private CharacterSelectController controller;

		private MPButton buttonTemplate;

		private MPButton? settingsStyleTemplate;

		private Image? settingsPanelStyleTemplate;

		private GameObject openButtonObject;

		private GameObject overlayObject;

		private GameObject modulesPageObject;

		private GameObject modePageObject;

		private GameObject rulesPageObject;

		private GameObject teamsPageObject;

		private GameObject loadoutPageObject;

		private RectTransform overlayRect;

		private RectTransform panelRect;

		private MPButton modulesTabButton;

		private MPButton modeTabButton;

		private MPButton rulesTabButton;

		private MPButton teamsTabButton;

		private MPButton loadoutTabButton;

		private MPButton loadoutBudgetDecreaseButton;

		private MPButton loadoutBudgetIncreaseButton;

		private MPButton? firstRulesButton;

		private HGTextMeshProUGUI pageHintText;

		private HGTextMeshProUGUI currentChoiceText;

		private HGTextMeshProUGUI rosterText;

		private HGTextMeshProUGUI loadoutCategoryText;

		private HGTextMeshProUGUI loadoutBudgetText;

		private HGTextMeshProUGUI loadoutSelectedText;

		private HGTextMeshProUGUI loadoutPresetStatusText;

		private RectTransform loadoutGrid;

		private int currentPage;

		private bool wasVisible;

		private bool wasPvPConfigurationAvailable;

		private int localLobbySelection = -1;

		private float nextTeamRefreshTime;

		private float nextLoadoutRefreshTime;

		private StartingLoadoutCategory loadoutCategory;

		private void Start()
		{
			controller = ((Component)this).GetComponent<CharacterSelectController>();
			if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)controller.readyButton))
			{
				((Behaviour)this).enabled = false;
				return;
			}
			buttonTemplate = controller.readyButton;
			try
			{
				LoadNativeSettingsStyle();
				CreateOpenButton();
				CreatePanel();
				ResonatorModules.StateChanged -= OnModuleStateChanged;
				ResonatorModules.StateChanged += OnModuleStateChanged;
				ResonatorModules.RequestSync();
				RefreshVisibility(force: true);
				RefreshPvPTabAvailability(force: true);
				Plugin.Log.LogDebug((object)"Resonators of the Soul lobby settings UI initialized.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to initialize the PvP lobby settings UI: {arg}");
				if (Object.op_Implicit((Object)(object)openButtonObject))
				{
					Object.Destroy((Object)(object)openButtonObject);
				}
				if (Object.op_Implicit((Object)(object)overlayObject))
				{
					Object.Destroy((Object)(object)overlayObject);
				}
				((Behaviour)this).enabled = false;
			}
		}

		private void OnDestroy()
		{
			ResonatorModules.StateChanged -= OnModuleStateChanged;
			if (Object.op_Implicit((Object)(object)openButtonObject))
			{
				Object.Destroy((Object)(object)openButtonObject);
			}
			if (Object.op_Implicit((Object)(object)overlayObject))
			{
				Object.Destroy((Object)(object)overlayObject);
			}
		}

		private void Update()
		{
			RefreshVisibility(force: false);
			RefreshPvPTabAvailability(force: false);
			if (Object.op_Implicit((Object)(object)overlayObject) && overlayObject.activeSelf)
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					ClosePanel();
				}
				else if (currentPage == 3 && Time.unscaledTime >= nextTeamRefreshTime)
				{
					nextTeamRefreshTime = Time.unscaledTime + 0.25f;
					RefreshTeamPage();
				}
				else if (currentPage == 4 && Time.unscaledTime >= nextLoadoutRefreshTime)
				{
					nextLoadoutRefreshTime = Time.unscaledTime + 0.15f;
					RefreshLoadoutPage();
				}
			}
		}

		private static bool IsPvPModeSelected()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			PreGameController instance = PreGameController.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return false;
			}
			Run gameModePrefabComponent = GameModeCatalog.GetGameModePrefabComponent(instance.gameModeIndex);
			if (Object.op_Implicit((Object)(object)gameModePrefabComponent))
			{
				return ((Object)((Component)gameModePrefabComponent).gameObject).name == "WaterBucketPvPModeRun";
			}
			return false;
		}

		private static bool IsPvPConfigurationAvailable()
		{
			if (ResonatorModules.GetLobbyEnabled(ResonatorModules.ModuleKind.PvP))
			{
				return IsPvPModeSelected();
			}
			return false;
		}

		private void RefreshVisibility(bool force)
		{
			bool flag = Object.op_Implicit((Object)(object)controller) && ((Component)controller).gameObject.activeInHierarchy;
			if (force || flag != wasVisible)
			{
				wasVisible = flag;
				if (Object.op_Implicit((Object)(object)openButtonObject))
				{
					openButtonObject.SetActive(flag);
				}
				if (!flag && Object.op_Implicit((Object)(object)overlayObject))
				{
					overlayObject.SetActive(false);
				}
			}
		}

		private void OnModuleStateChanged()
		{
			RefreshValues();
			RefreshPvPTabAvailability(force: true);
		}

		private void CreateOpenButton()
		{
			//IL_0042: 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_0058: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007c: 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_0089: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			openButtonObject = Object.Instantiate<GameObject>(((Component)buttonTemplate).gameObject, ((Component)buttonTemplate).transform.parent, false);
			((Object)openButtonObject).name = "ResonatorsOfTheSoulSettingsButton";
			RectTransform val = (RectTransform)openButtonObject.transform;
			RectTransform val2 = (RectTransform)((Component)buttonTemplate).transform;
			val.anchorMin = val2.anchorMin;
			val.anchorMax = val2.anchorMax;
			val.pivot = val2.pivot;
			val.sizeDelta = val2.sizeDelta;
			Vector2 anchoredPosition = val2.anchoredPosition;
			Rect rect = val2.rect;
			val.anchoredPosition = anchoredPosition + new Vector2(0f, ((Rect)(ref rect)).height + 10f);
			MPButton component = openButtonObject.GetComponent<MPButton>();
			ResetButton(component, "Resonators of the Soul 设置", tokenized: false);
			ApplyNativeSettingsStyle(component);
			((UnityEvent)((Button)component).onClick).AddListener(new UnityAction(OpenPanel));
		}

		private void CreatePanel()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0170: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Expected O, but got Unknown
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Expected O, but got Unknown
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Expected O, but got Unknown
			Canvas componentInParent = ((Component)controller).GetComponentInParent<Canvas>();
			Canvas val = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.rootCanvas : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Character select UI has no root Canvas.");
			}
			overlayObject = new GameObject("ResonatorsOfTheSoulSettingsOverlay", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			overlayObject.layer = ((Component)val).gameObject.layer;
			overlayObject.transform.SetParent(((Component)val).transform, false);
			overlayObject.transform.SetAsLastSibling();
			overlayRect = (RectTransform)overlayObject.transform;
			Stretch(overlayRect);
			Image component = overlayObject.GetComponent<Image>();
			((Graphic)component).color = new Color(0.006f, 0.011f, 0.019f, 0.86f);
			((Graphic)component).raycastTarget = true;
			GameObject val2 = new GameObject("Panel", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Outline)
			});
			val2.layer = overlayObject.layer;
			val2.transform.SetParent(overlayObject.transform, false);
			panelRect = (RectTransform)val2.transform;
			panelRect.anchorMin = new Vector2(0.16f, 0.045f);
			panelRect.anchorMax = new Vector2(0.84f, 0.955f);
			panelRect.offsetMin = Vector2.zero;
			panelRect.offsetMax = Vector2.zero;
			Image component2 = val2.GetComponent<Image>();
			((Graphic)component2).color = new Color(0.025f, 0.043f, 0.061f, 0.985f);
			ApplyNativePanelStyle(component2);
			Outline component3 = val2.GetComponent<Outline>();
			((Shadow)component3).effectColor = new Color(0.46f, 0.67f, 0.74f, 0.55f);
			((Shadow)component3).effectDistance = new Vector2(1f, -1f);
			CreateAccentStrip(val2.transform);
			GameObject val3 = new GameObject("Content", new Type[2]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup)
			});
			val3.layer = val2.layer;
			val3.transform.SetParent(val2.transform, false);
			RectTransform val4 = (RectTransform)val3.transform;
			Stretch(val4);
			val4.offsetMin = new Vector2(34f, 24f);
			val4.offsetMax = new Vector2(-34f, -22f);
			VerticalLayoutGroup component4 = val3.GetComponent<VerticalLayoutGroup>();
			((LayoutGroup)component4).padding = new RectOffset(4, 4, 2, 2);
			((HorizontalOrVerticalLayoutGroup)component4).spacing = 6f;
			((LayoutGroup)component4).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = true;
			((TMP_Text)CreateText(val3.transform, "Resonators of the Soul 设置", 31f, (FontStyles)1, (TextAlignmentOptions)514, 44f, tokenized: false)).characterSpacing = 1.5f;
			CreateTabRow(val3.transform);
			pageHintText = CreateText(val3.transform, string.Empty, 16f, (FontStyles)0, (TextAlignmentOptions)514, 30f, tokenized: false);
			((Graphic)pageHintText).color = new Color(0.73f, 0.81f, 0.84f, 1f);
			modulesPageObject = CreateModulesPage(val3.transform);
			modePageObject = CreateModePage(val3.transform);
			rulesPageObject = CreateRulesPage(val3.transform);
			teamsPageObject = CreateTeamsPage(val3.transform);
			loadoutPageObject = CreateLoadoutPage(val3.transform);
			((UnityEvent)((Button)CloneButton(val3.transform, "WATERBUCKET_PVP_SETTINGS_CLOSE", tokenized: true, -1f, 45f)).onClick).AddListener(new UnityAction(ClosePanel));
			overlayObject.SetActive(false);
			Plugin.Log.LogDebug((object)("Resonators of the Soul settings overlay attached to root Canvas '" + ((Object)val).name + "'."));
		}

		private void CreateAccentStrip(Transform parent)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Accent", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(0f, 1f);
			val2.pivot = new Vector2(0f, 0.5f);
			val2.sizeDelta = new Vector2(4f, 0f);
			val2.anchoredPosition = Vector2.zero;
			((Graphic)val.GetComponent<Image>()).color = new Color(0.35f, 0.75f, 0.91f, 0.9f);
		}

		private void CreateTabRow(Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			GameObject val = new GameObject("Tabs", new Type[3]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup),
				typeof(LayoutElement)
			});
			val.layer = ((Component)parent).gameObject.layer;
			val.transform.SetParent(parent, false);
			val.GetComponent<LayoutElement>().preferredHeight = 48f;
			HorizontalLayoutGroup component = val.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).spacing = 5f;
			((LayoutGroup)component).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true;
			modulesTabButton = CloneButton(val.transform, "模块", tokenized: false, -1f, 46f);
			modeTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_MODE", tokenized: true, -1f, 46f);
			rulesTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_RULES", tokenized: true, -1f, 46f);
			teamsTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_TEAMS", tokenized: true, -1f, 46f);
			loadoutTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_LOADOUT", tokenized: true, -1f, 46f);
			((UnityEvent)((Button)modulesTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(0);
			});
			((UnityEvent)((Button)modeTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(1);
			});
			((UnityEvent)((Button)rulesTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(2);
			});
			((UnityEvent)((Button)teamsTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(3);
			});
			((UnityEvent)((Button)loadoutTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(4);
			});
		}

		private GameObject CreateModulesPage(Transform parent)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = CreatePage(parent, "ModulesPage", 628f);
			Transform transform = obj.transform;
			CreateSectionHeader(transform, "功能模块", tokenized: false);
			AddModuleToggleRow(transform, "强化难度", ResonatorModules.ModuleKind.Difficulties);
			AddModuleToggleRow(transform, "神器", ResonatorModules.ModuleKind.Artifacts);
			AddModuleToggleRow(transform, "PvP", ResonatorModules.ModuleKind.PvP);
			HGTextMeshProUGUI obj2 = CreateText(transform, "模块由房主统一控制,并同步给房间内所有玩家。关闭模块不会移除其联网目录内容,避免多人配置不一致。", 17f, (FontStyles)0, (TextAlignmentOptions)257, 96f, tokenized: false);
			((TMP_Text)obj2).enableWordWrapping = true;
			((Graphic)obj2).color = new Color(0.73f, 0.81f, 0.84f, 1f);
			return obj;
		}

		private GameObject CreateModePage(Transform parent)
		{
			GameObject obj = CreatePage(parent, "ModePage", 628f);
			Transform transform = obj.transform;
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_MATCH_RULE");
			AddChoiceRow(transform, "WATERBUCKET_PVP_SETTINGS_MATCH_MODE", GetMatchModeText, delegate
			{
				CycleMatchMode(-1);
			}, delegate
			{
				CycleMatchMode(1);
			});
			AddIntegerRow(transform, "WATERBUCKET_PVP_SETTINGS_LIVES", PvPConfig.LivesPerPlayer, 1, 1, () => 99);
			AddIntegerRow(transform, "WATERBUCKET_PVP_SETTINGS_TIME_LIMIT", PvPConfig.TimeLimitMinutes, 1, 1, () => 120);
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_TEAMS");
			AddToggleRow(transform, "WATERBUCKET_PVP_SETTINGS_MODE", () => (!PvPConfig.IsFfa) ? Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_MODE") : "FFA", delegate
			{
				PvPConfig.AssignmentMode.Value = (PvPConfig.IsFfa ? "Team" : "FFA");
			});
			AddIntegerRow(transform, "WATERBUCKET_PVP_SETTINGS_TEAM_COUNT", PvPConfig.TeamCount, 1, 2, () => Math.Max(2, PvPTeamRegistry.Count));
			AddToggleRow(transform, "WATERBUCKET_PVP_SETTINGS_FRIENDLY_FIRE", () => BoolText(PvPConfig.FriendlyFire.Value), delegate
			{
				PvPConfig.FriendlyFire.Value = !PvPConfig.FriendlyFire.Value;
			});
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_RESPAWN");
			AddDynamicFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_RESPAWN_DELAY", () => PvPConfig.CurrentRespawnDelaySeconds, delegate(float value)
			{
				if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives)
				{
					PvPConfig.LimitedLivesRespawnDelaySeconds.Value = value;
				}
				else
				{
					PvPConfig.RespawnDelaySeconds.Value = value;
				}
			}, 5f, 0.5f, () => (PvPConfig.CurrentMatchMode != PvPConfig.MatchModeKind.LimitedLives) ? 60f : 180f, SecondsText);
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_RESPAWN_PROTECTION", PvPConfig.RespawnInvulnerabilitySeconds, 0.5f, 0f, 15f, SecondsText);
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_ROUTE");
			AddToggleRow(transform, "WATERBUCKET_PVP_SETTINGS_STAGE_FIVE_ROUTE", () => Language.GetString(PvPConfig.StageFiveDefaultsToLoop ? "WATERBUCKET_PVP_SETTINGS_ROUTE_LOOP" : "WATERBUCKET_PVP_SETTINGS_ROUTE_MOON"), delegate
			{
				PvPConfig.StageFiveRoute.Value = (PvPConfig.StageFiveDefaultsToLoop ? "Moon" : "Loop");
			});
			return obj;
		}

		private GameObject CreateRulesPage(Transform parent)
		{
			GameObject obj = CreatePage(parent, "RulesPage", 628f);
			Transform transform = obj.transform;
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_MATCH");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_PLAYER_PLAYER", PvPConfig.PlayerToPlayerDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_MINION_PLAYER", PvPConfig.MinionToPlayerDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_PLAYER_MINION", PvPConfig.PlayerToMinionDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_MINION_MINION", PvPConfig.MinionToMinionDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_CONTROL_DURATION", PvPConfig.PlayerControlDurationMultiplier, 0.1f, 0f, 5f, (float value) => $"×{value:0.00}");
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_SPAWN");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_FALLBACK_DISTANCE", PvPConfig.MinimumSpawnDistance, 5f, 10f, 200f, (float value) => $"{value:0} m");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_TEAM_RADIUS", PvPConfig.TeamSpawnRadius, 2.5f, 0f, 50f, (float value) => $"{value:0.#} m");
			AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_SPAWN_PROTECTION", PvPConfig.SpawnInvulnerabilitySeconds, 0.5f, 0f, 15f, SecondsText);
			return obj;
		}

		private GameObject CreateTeamsPage(Transform parent)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreatePage(parent, "TeamsPage", 628f);
			Transform transform = val.transform;
			currentChoiceText = CreateText(transform, string.Empty, 20f, (FontStyles)1, (TextAlignmentOptions)514, 42f, tokenized: false);
			((Graphic)currentChoiceText).color = new Color(0.88f, 0.95f, 1f, 1f);
			GameObject val2 = new GameObject("TeamGrid", new Type[3]
			{
				typeof(RectTransform),
				typeof(GridLayoutGroup),
				typeof(LayoutElement)
			});
			val2.layer = val.layer;
			val2.transform.SetParent(transform, false);
			LayoutElement component = val2.GetComponent<LayoutElement>();
			component.preferredHeight = 188f;
			component.minHeight = 188f;
			GridLayoutGroup component2 = val2.GetComponent<GridLayoutGroup>();
			component2.cellSize = new Vector2(206f, 54f);
			component2.spacing = new Vector2(10f, 9f);
			component2.constraint = (Constraint)1;
			component2.constraintCount = 3;
			((LayoutGroup)component2).childAlignment = (TextAnchor)1;
			CreateTeamButton(val2.transform, -1);
			for (int i = 0; i < PvPTeamRegistry.Count; i++)
			{
				CreateTeamButton(val2.transform, i);
			}
			CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_TEAM_ROSTER");
			rosterText = CreateText(transform, string.Empty, 18f, (FontStyles)0, (TextAlignmentOptions)257, 250f, tokenized: false);
			((Component)rosterText).GetComponent<LayoutElement>().flexibleHeight = 1f;
			((TMP_Text)rosterText).enableWordWrapping = true;
			((Graphic)rosterText).color = new Color(0.8f, 0.87f, 0.9f, 1f);
			return val;
		}

		private GameObject CreateLoadoutPage(Transform parent)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Expected O, but got Unknown
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Expected O, but got Unknown
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Expected O, but got Unknown
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Expected O, but got Unknown
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Expected O, but got Unknown
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_055b: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00aa: Expected O, but got Unknown
			GameObject val = CreatePage(parent, "LoadoutPage", 628f);
			Transform transform = val.transform;
			CreateSectionHeader(transform, "WATERBUCKET_PVP_LOADOUT_PRESETS");
			Transform parent2 = CreateRow(transform);
			for (int i = 0; i < 5; i++)
			{
				int capturedSlot = i;
				MPButton val2 = CloneButton(parent2, string.Empty, tokenized: false, 112f, 44f);
				((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate
				{
					LoadLoadoutPreset(capturedSlot);
				});
				EventTrigger obj = ((Component)val2).gameObject.GetComponent<EventTrigger>() ?? ((Component)val2).gameObject.AddComponent<EventTrigger>();
				Entry val3 = new Entry
				{
					eventID = (EventTriggerType)4
				};
				((UnityEvent<BaseEventData>)(object)val3.callback).AddListener((UnityAction<BaseEventData>)delegate(BaseEventData data)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Invalid comparison between Unknown and I4
					PointerEventData val9 = (PointerEventData)(object)((data is PointerEventData) ? data : null);
					if (val9 != null && (int)val9.button == 1)
					{
						SaveLoadoutPreset(capturedSlot);
					}
				});
				obj.triggers.Add(val3);
				TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.fontSize = 14f;
					componentInChildren.alignment = (TextAlignmentOptions)514;
				}
				loadoutPresetButtons.Add((val2, componentInChildren, capturedSlot));
			}
			loadoutPresetStatusText = CreateText(transform, "WATERBUCKET_PVP_LOADOUT_PRESET_HINT", 14f, (FontStyles)0, (TextAlignmentOptions)514, 25f, tokenized: true);
			((Graphic)loadoutPresetStatusText).color = new Color(0.72f, 0.8f, 0.84f, 1f);
			Transform val4 = CreateRow(transform);
			CreateRowLabel(val4, "WATERBUCKET_PVP_LOADOUT_CATEGORY");
			loadoutCategoryText = CreateValueText(val4);
			MPButton val5 = CloneButton(val4, "‹", tokenized: false, 58f, 38f);
			MPButton obj2 = CloneButton(val4, "›", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)val5).onClick).AddListener((UnityAction)delegate
			{
				CycleLoadoutCategory(-1);
			});
			((UnityEvent)((Button)obj2).onClick).AddListener((UnityAction)delegate
			{
				CycleLoadoutCategory(1);
			});
			Transform val6 = CreateRow(transform);
			CreateRowLabel(val6, "WATERBUCKET_PVP_LOADOUT_ALLOWANCE");
			loadoutBudgetText = CreateValueText(val6);
			loadoutBudgetDecreaseButton = CloneButton(val6, "−", tokenized: false, 58f, 38f);
			loadoutBudgetIncreaseButton = CloneButton(val6, "+", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)loadoutBudgetDecreaseButton).onClick).AddListener((UnityAction)delegate
			{
				ChangeLoadoutBudget(-1);
			});
			((UnityEvent)((Button)loadoutBudgetIncreaseButton).onClick).AddListener((UnityAction)delegate
			{
				ChangeLoadoutBudget(1);
			});
			loadoutSelectedText = CreateText(transform, string.Empty, 19f, (FontStyles)1, (TextAlignmentOptions)514, 34f, tokenized: false);
			((Graphic)CreateText(transform, "WATERBUCKET_PVP_LOADOUT_CLICK_HINT", 15f, (FontStyles)0, (TextAlignmentOptions)514, 27f, tokenized: true)).color = new Color(0.72f, 0.8f, 0.84f, 1f);
			GameObject val7 = new GameObject("LoadoutScroll", new Type[5]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Mask),
				typeof(ScrollRect),
				typeof(LayoutElement)
			});
			val7.layer = val.layer;
			val7.transform.SetParent(transform, false);
			LayoutElement component = val7.GetComponent<LayoutElement>();
			component.minHeight = 300f;
			component.flexibleHeight = 1f;
			((Graphic)val7.GetComponent<Image>()).color = new Color(0.018f, 0.032f, 0.045f, 0.94f);
			val7.GetComponent<Mask>().showMaskGraphic = true;
			GameObject val8 = new GameObject("LoadoutGrid", new Type[3]
			{
				typeof(RectTransform),
				typeof(GridLayoutGroup),
				typeof(ContentSizeFitter)
			});
			val8.layer = val.layer;
			val8.transform.SetParent(val7.transform, false);
			loadoutGrid = (RectTransform)val8.transform;
			loadoutGrid.anchorMin = new Vector2(0f, 1f);
			loadoutGrid.anchorMax = new Vector2(1f, 1f);
			loadoutGrid.pivot = new Vector2(0.5f, 1f);
			loadoutGrid.offsetMin = new Vector2(8f, 0f);
			loadoutGrid.offsetMax = new Vector2(-8f, 0f);
			GridLayoutGroup component2 = val8.GetComponent<GridLayoutGroup>();
			component2.cellSize = new Vector2(166f, 72f);
			component2.spacing = new Vector2(8f, 8f);
			((LayoutGroup)component2).padding = new RectOffset(8, 8, 8, 8);
			component2.constraint = (Constraint)1;
			component2.constraintCount = 4;
			((LayoutGroup)component2).childAlignment = (TextAnchor)1;
			val8.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			ScrollRect component3 = val7.GetComponent<ScrollRect>();
			component3.viewport = (RectTransform)val7.transform;
			component3.content = loadoutGrid;
			component3.horizontal = false;
			component3.vertical = true;
			component3.movementType = (MovementType)2;
			component3.scrollSensitivity = 28f;
			((UnityEvent)((Button)CloneButton(transform, "WATERBUCKET_PVP_LOADOUT_CLEAR", tokenized: true, -1f, 40f)).onClick).AddListener((UnityAction)delegate
			{
				PvPStartingLoadoutManager.ClearCategory(loadoutCategory);
				RefreshLoadoutPage();
			});
			RebuildLoadoutGrid();
			return val;
		}

		private void SaveLoadoutPreset(int slotIndex)
		{
			int num = PvPLoadoutPresetStore.SaveSlot(slotIndex);
			((TMP_Text)loadoutPresetStatusText).text = string.Format(Language.GetString("WATERBUCKET_PVP_LOADOUT_PRESET_SAVED"), slotIndex + 1, num);
			RefreshLoadoutPresetButtons();
		}

		private void LoadLoadoutPreset(int slotIndex)
		{
			LoadoutPresetLoadResult loadoutPresetLoadResult = PvPLoadoutPresetStore.LoadSlot(slotIndex);
			if (!loadoutPresetLoadResult.Success)
			{
				((TMP_Text)loadoutPresetStatusText).text = Language.GetString(PvPLoadoutPresetStore.IsSlotSaved(slotIndex) ? "WATERBUCKET_PVP_LOADOUT_PRESET_INVALID" : "WATERBUCKET_PVP_LOADOUT_PRESET_EMPTY");
				return;
			}
			int num = PvPStartingLoadoutManager.RequestSelectionReplacement(loadoutPresetLoadResult.Selections);
			int num2 = Math.Max(0, loadoutPresetLoadResult.SavedCount - num);
			((TMP_Text)loadoutPresetStatusText).text = string.Format(Language.GetString("WATERBUCKET_PVP_LOADOUT_PRESET_LOADED"), slotIndex + 1, num, num2);
			RefreshLoadoutPage();
		}

		private void RefreshLoadoutPresetButtons()
		{
			//IL_0098: 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)
			foreach (var (val, val2, num) in loadoutPresetButtons)
			{
				if (Object.op_Implicit((Object)(object)val2))
				{
					bool flag = PvPLoadoutPresetStore.IsSlotSaved(num);
					val2.text = string.Format(Language.GetString(flag ? "WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_SAVED" : "WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_EMPTY"), num + 1);
					((Graphic)val2).color = (flag ? new Color(1f, 0.76f, 0.3f, 1f) : new Color(0.78f, 0.86f, 0.9f, 1f));
					((Selectable)val).interactable = true;
				}
			}
		}

		private void CycleLoadoutCategory(int direction)
		{
			int num = 9;
			int num2 = ((int)loadoutCategory + direction) % num;
			if (num2 < 0)
			{
				num2 += num;
			}
			loadoutCategory = (StartingLoadoutCategory)num2;
			RebuildLoadoutGrid();
			PvPStartingLoadoutManager.RequestSync();
			RefreshLoadoutPage();
		}

		private void ChangeLoadoutBudget(int delta)
		{
			if (NetworkServer.active)
			{
				ConfigEntry<int> budgetEntry = PvPStartingLoadoutManager.GetBudgetEntry(loadoutCategory);
				budgetEntry.Value = Math.Clamp(budgetEntry.Value + delta, 0, PvPStartingLoadoutManager.GetMaximumBudget(loadoutCategory));
				PvPStartingLoadoutManager.NotifyHostBudgetsChanged();
				RefreshLoadoutPage();
			}
		}

		private void RebuildLoadoutGrid()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)loadoutGrid))
			{
				return;
			}
			foreach (Transform item in (Transform)loadoutGrid)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			loadoutButtons.Clear();
			foreach (StartingLoadoutOption option in PvPStartingLoadoutManager.GetAvailableDefinitions(loadoutCategory))
			{
				MPButton val = CloneButton((Transform)(object)loadoutGrid, string.Empty, tokenized: false, 166f, 72f);
				((UnityEvent)((Button)val).onClick).AddListener((UnityAction)delegate
				{
					PvPStartingLoadoutManager.RequestSelectionChange(loadoutCategory, option.DefinitionIndex, option.IsEquipment, 1);
					RefreshLoadoutPage();
				});
				TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.fontSize = 13f;
					componentInChildren.alignment = (TextAlignmentOptions)514;
					componentInChildren.enableWordWrapping = true;
					RectTransform val2 = (RectTransform)componentInChildren.transform;
					val2.offsetMin += new Vector2(44f, 0f);
				}
				GameObject val3 = new GameObject("Icon", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				})
				{
					layer = ((Component)val).gameObject.layer
				};
				val3.transform.SetParent(((Component)val).transform, false);
				RectTransform val4 = (RectTransform)val3.transform;
				val4.anchorMin = new Vector2(0f, 0.5f);
				val4.anchorMax = new Vector2(0f, 0.5f);
				val4.pivot = new Vector2(0f, 0.5f);
				val4.anchoredPosition = new Vector2(6f, 0f);
				val4.sizeDelta = new Vector2(40f, 40f);
				Image component = val3.GetComponent<Image>();
				component.sprite = PvPStartingLoadoutManager.GetDefinitionIcon(loadoutCategory, option.DefinitionIndex, option.IsEquipment);
				component.preserveAspect = true;
				((Graphic)component).raycastTarget = false;
				AddLoadoutTooltip(((Component)val).gameObject, option);
				EventTrigger obj = ((Component)val).gameObject.GetComponent<EventTrigger>() ?? ((Component)val).gameObject.AddComponent<EventTrigger>();
				Entry val5 = new Entry
				{
					eventID = (EventTriggerType)4
				};
				((UnityEvent<BaseEventData>)(object)val5.callback).AddListener((UnityAction<BaseEventData>)delegate(BaseEventData data)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Invalid comparison between Unknown and I4
					PointerEventData val6 = (PointerEventData)(object)((data is PointerEventData) ? data : null);
					if (val6 != null && (int)val6.button == 1)
					{
						PvPStartingLoadoutManager.RequestSelectionChange(loadoutCategory, option.DefinitionIndex, option.IsEquipment, -1);
						RefreshLoadoutPage();
					}
				});
				obj.triggers.Add(val5);
				loadoutButtons.Add((val, option, componentInChildren));
			}
		}

		private static void AddLoadoutTooltip(GameObject target, StartingLoadoutOption option)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			TooltipProvider val = target.GetComponent<TooltipProvider>() ?? target.AddComponent<TooltipProvider>();
			val.overrideTitleText = string.Empty;
			val.overrideBodyText = string.Empty;
			val.bodyColor = Color.white;
			val.AllowTooltipOnNavigationSelect = true;
			val.disableTitleRichText = false;
			val.disableBodyRichText = false;
			if (option.IsEquipment)
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)option.DefinitionIndex);
				if (!Object.op_Implicit((Object)(object)equipmentDef))
				{
					val.titleToken = string.Empty;
					val.bodyToken = string.Empty;
				}
				else
				{
					val.titleToken = equipmentDef.nameToken;
					val.bodyToken = (string.IsNullOrEmpty(equipmentDef.descriptionToken) ? equipmentDef.pickupToken : equipmentDef.descriptionToken);
					val.titleColor = Color32.op_Implicit(ColorCatalog.GetColor(equipmentDef.colorIndex));
				}
				return;
			}
			ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)option.DefinitionIndex);
			if (!Object.op_Implicit((Object)(object)itemDef))
			{
				val.titleToken = string.Empty;
				val.bodyToken = string.Empty;
				return;
			}
			val.titleToken = itemDef.nameToken;
			val.bodyToken = (string.IsNullOrEmpty(itemDef.descriptionToken) ? itemDef.pickupToken : itemDef.descriptionToken);
			ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(itemDef.tier);
			val.titleColor = (Object.op_Implicit((Object)(object)itemTierDef) ? Color32.op_Implicit(ColorCatalog.GetColor(itemTierDef.colorIndex)) : Color.white);
		}

		private void RefreshLoadoutPage()
		{
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)loadoutCategoryText) || !Object.op_Implicit((Object)(object)loadoutBudgetText) || !Object.op_Implicit((Object)(object)loadoutSelectedText))
			{
				return;
			}
			int clientBudget = PvPStartingLoadoutManager.GetClientBudget(loadoutCategory);
			int clientSelectedCount = PvPStartingLoadoutManager.GetClientSelectedCount(loadoutCategory);
			((TMP_Text)loadoutCategoryText).text = Language.GetString(GetLoadoutCategoryToken(loadoutCategory));
			((TMP_Text)loadoutBudgetText).text = clientBudget.ToString();
			((TMP_Text)loadoutSelectedText).text = string.Format(Language.GetString("WATERBUCKET_PVP_LOADOUT_SELECTED"), clientSelectedCount, clientBudget);
			((Selectable)loadoutBudgetDecreaseButton).interactable = NetworkServer.active && clientBudget > 0;
			((Selectable)loadoutBudgetIncreaseButton).interactable = NetworkServer.active && clientBudget < PvPStartingLoadoutManager.GetMaximumBudget(loadoutCategory);
			RefreshLoadoutPresetButtons();
			foreach (var loadoutButton in loadoutButtons)
			{
				MPButton item = loadoutButton.Button;
				StartingLoadoutOption item2 = loadoutButton.Option;
				TMP_Text item3 = loadoutButton.Label;
				int clientChoiceCount = PvPStartingLoadoutManager.GetClientChoiceCount(loadoutCategory, item2.DefinitionIndex, item2.IsEquipment);
				string definitionName = PvPStartingLoadoutManager.GetDefinitionName(loadoutCategory, item2.DefinitionIndex, item2.IsEquipment);
				item3.text = ((clientChoiceCount > 0) ? $"{definitionName}\n×{clientChoiceCount}" : definitionName);
				((Graphic)item3).color = (Color)((clientChoiceCount > 0) ? new Color(1f, 0.76f, 0.3f, 1f) : Color.white);
				((Selectable)item).interactable = clientChoiceCount > 0 || clientSelectedCount < clientBudget;
			}
		}

		private GameObject CreatePage(Transform parent, string name, float preferredHeight)
		{
			//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_0044: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup),
				typeof(LayoutElement)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.preferredHeight = preferredHeight;
			component.flexibleHeight = 1f;
			VerticalLayoutGroup component2 = val.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component2).spacing = 3f;
			((LayoutGroup)component2).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true;
			return val;
		}

		private void CreateSectionHeader(Transform parent, string textOrToken, bool tokenized = true)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SectionHeader", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(LayoutElement)
			});
			val.layer = ((Component)parent).gameObject.layer;
			val.transform.SetParent(parent, false);
			val.GetComponent<LayoutElement>().preferredHeight = 27f;
			((Graphic)val.GetComponent<Image>()).color = new Color(0.08f, 0.16f, 0.21f, 0.92f);
			HGTextMeshProUGUI obj = CreateText(val.transform, textOrToken, 15f, (FontStyles)1, (TextAlignmentOptions)4097, 27f, tokenized);
			RectTransform val2 = (RectTransform)((TMP_Text)obj).transform;
			Stretch(val2);
			val2.offsetMin = new Vector2(12f, 0f);
			val2.offsetMax = new Vector2(-8f, 0f);
			((Graphic)obj).color = new Color(0.49f, 0.82f, 0.96f, 1f);
		}

		private void CreateTeamButton(Transform parent, int teamId)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			MPButton val = CloneButton(parent, GetTeamButtonText(teamId), tokenized: false, 206f, 54f);
			((UnityEvent)((Button)val).onClick).AddListener((UnityAction)delegate
			{
				ChooseTeam(teamId);
			});
			teamButtons.Add((val, teamId));
		}

		private void AddModuleToggleRow(Transform parent, string label, ResonatorModules.ModuleKind module)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			Transform val = CreateRow(parent);
			LayoutElement component = ((Component)CreateText(val, label, 17f, (FontStyles)0, (TextAlignmentOptions)4097, 36f, tokenized: false)).GetComponent<LayoutElement>();
			component.preferredWidth = 400f;
			component.flexibleWidth = 2.8f;
			HGTextMeshProUGUI valueText = CreateValueText(val);
			MPButton toggleButton = CloneButton(val, "切换", tokenized: false, 124f, 38f);
			((UnityEvent)((Button)toggleButton).onClick).AddListener((UnityAction)delegate
			{
				if (NetworkServer.active)
				{
					bool lobbyEnabled = ResonatorModules.GetLobbyEnabled(module);
					ResonatorModules.SetHostEnabled(module, !lobbyEnabled);
					RefreshValues();
					RefreshPvPTabAvailability(force: true);
				}
			});
			valueRefreshers.Add(delegate
			{
				((TMP_Text)valueText).text = BoolText(ResonatorModules.GetLobbyEnabled(module));
				((Selectable)toggleButton).interactable = NetworkServer.active;
			});
		}

		private void AddToggleRow(Transform parent, string labelToken, Func<string> getValue, Action toggle)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			Transform val = CreateRow(parent);
			CreateRowLabel(val, labelToken);
			HGTextMeshProUGUI valueText = CreateValueText(val);
			MPButton val2 = CloneButton(val, "‹", tokenized: false, 58f, 38f);
			MPButton obj = CloneButton(val, "›", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate
			{
				toggle();
				RefreshValues();
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				toggle();
				RefreshValues();
			});
			if (firstRulesButton == null)
			{
				firstRulesButton = val2;
			}
			valueRefreshers.Add(delegate
			{
				((TMP_Text)valueText).text = getValue();
			});
		}

		private void AddChoiceRow(Transform parent, string labelToken, Func<string> getValue, Action previousChoice, Action nextChoice)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			Transform val = CreateRow(parent);
			CreateRowLabel(val, labelToken);
			HGTextMeshProUGUI valueText = CreateValueText(val);
			MPButton val2 = CloneButton(val, "‹", tokenized: false, 58f, 38f);
			MPButton obj = CloneButton(val, "›", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate
			{
				previousChoice();
				RefreshValues();
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				nextChoice();
				RefreshValues();
			});
			valueRefreshers.Add(delegate
			{
				((TMP_Text)valueText).text = getValue();
			});
		}

		private void AddIntegerRow(Transform parent, string labelToken, ConfigEntry<int> entry, int step, int minimum, Func<int> getMaximum)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			Transform val = CreateRow(parent);
			CreateRowLabel(val, labelToken);
			HGTextMeshProUGUI valueText = CreateValueText(val);
			MPButton val2 = CloneButton(val, "−", tokenized: false, 58f, 38f);
			MPButton obj = CloneButton(val, "+", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate
			{
				entry.Value = Math.Clamp(entry.Value - step, minimum, getMaximum());
				RefreshValues();
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				entry.Value = Math.Clamp(entry.Value + step, minimum, getMaximum());
				RefreshValues();
			});
			if (firstRulesButton == null)
			{
				firstRulesButton = val2;
			}
			valueRefreshers.Add(delegate
			{
				((TMP_Text)valueText).text = entry.Value.ToString();
			});
		}

		private void AddFloatRow(Transform parent, string labelToken, ConfigEntry<float> entry, float step, float minimum, float maximum, Func<float, string> formatter)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			Transform val = CreateRow(parent);
			CreateRowLabel(val, labelToken);
			HGTextMeshProUGUI valueText = CreateValueText(val);
			MPButton val2 = CloneButton(val, "−", tokenized: false, 58f, 38f);
			MPButton obj = CloneButton(val, "+", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate
			{
				entry.Value = Mathf.Clamp(entry.Value - step, minimum, maximum);
				RefreshValues();
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				entry.Value = Mathf.Clamp(entry.Value + step, minimum, maximum);
				RefreshValues();
			});
			if (firstRulesButton == null)
			{
				firstRulesButton = val2;
			}
			valueRefreshers.Add(delegate
			{
				((TMP_Text)valueText).text = formatter(entry.Value);
			});
		}

		private void AddDynamicFloatRow(Transform parent, string labelToken, Func<float> getValue, Action<float> setValue, float step, float minimum, Func<float> getMaximum, Func<float, string> formatter)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			Transform val = CreateRow(parent);
			CreateRowLabel(val, labelToken);
			HGTextMeshProUGUI valueText = CreateValueText(val);
			MPButton val2 = CloneButton(val, "−", tokenized: false, 58f, 38f);
			MPButton obj = CloneButton(val, "+", tokenized: false, 58f, 38f);
			((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate
			{
				setValue(Mathf.Clamp(getValue() - step, minimum, getMaximum()));
				RefreshValues();
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				setValue(Mathf.Clamp(getValue() + step, minimum, getMaximum()));
				RefreshValues();
			});
			valueRefreshers.Add(delegate
			{
				((TMP_Text)valueText).text = formatter(getValue());
			});
		}

		private Transform CreateRow(Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SettingRow", new Type[3]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup),
				typeof(LayoutElement)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.preferredHeight = 38f;
			component.minHeight = 32f;
			HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component2).spacing = 8f;
			((LayoutGroup)component2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = true;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false;
			return val.transform;
		}

		private void CreateRowLabel(Transform row, string labelToken)
		{
			LayoutElement component = ((Component)CreateText(row, labelToken, 17f, (FontStyles)0, (TextAlignmentOptions)4097, 36f, tokenized: true)).GetComponent<LayoutElement>();
			component.preferredWidth = 400f;
			component.flexibleWidth = 2.8f;
		}

		private HGTextMeshProUGUI CreateValueText(Transform row)
		{
			HGTextMeshProUGUI obj = CreateText(row, string.Empty, 17f, (FontStyles)1, (TextAlignmentOptions)514, 36f, tokenized: false);
			LayoutElement component = ((Component)obj).GetComponent<LayoutElement>();
			component.preferredWidth = 145f;
			component.flexibleWidth = 1f;
			return obj;
		}

		private HGTextMeshProUGUI CreateText(Transform parent, string textOrToken, float fontSize, FontStyles style, TextAlignmentOptions alignment, float preferredHeight, bool tokenized)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009b: 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)
			GameObject val = new GameObject("Text", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.SetActive(false);
			val.transform.SetParent(parent, false);
			HGTextMeshProUGUI val2 = val.AddComponent<HGTextMeshProUGUI>();
			TMP_Text componentInChildren = ((Component)buttonTemplate).GetComponentInChildren<TMP_Text>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				((TMP_Text)val2).font = componentInChildren.font;
				((TMP_Text)val2).fontSharedMaterial = componentInChildren.fontSharedMaterial;
			}
			((TMP_Text)val2).fontSize = fontSize;
			((TMP_Text)val2).fontStyle = style;
			((TMP_Text)val2).alignment = alignment;
			((Graphic)val2).color = Color.white;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).text = (tokenized ? Language.GetString(textOrToken) : textOrToken);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.preferredHeight = preferredHeight;
			component.minHeight = Math.Min(24f, preferredHeight);
			val.SetActive(true);
			return val2;
		}

		private MPButton CloneButton(Transform parent, string textOrToken, bool tokenized, float preferredWidth, float preferredHeight)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)buttonTemplate).gameObject, parent, false);
			((Object)val).name = "PvPSettingButton";
			val.SetActive(true);
			MPButton component = val.GetComponent<MPButton>();
			ResetButton(component, textOrToken, tokenized);
			ApplyNativeSettingsStyle(component);
			LayoutElement val2 = val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>();
			if (preferredWidth > 0f)
			{
				val2.preferredWidth = preferredWidth;
			}
			else
			{
				val2.flexibleWidth = 1f;
			}
			val2.preferredHeight = preferredHeight;
			val2.minHeight = Math.Min(32f, preferredHeight);
			return component;
		}

		private static void ResetButton(MPButton button, string textOrToken, bool tokenized)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			((Button)button).onClick = new ButtonClickedEvent();
			((Selectable)button).interactable = true;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)button).navigation = navigation;
			button.defaultFallbackButton = false;
			HGButton val = (HGButton)(object)((button is HGButton) ? button : null);
			if (val != null)
			{
				val.updateTextOnHover = false;
				val.hoverToken = string.Empty;
				((MPButton)val).defaultFallbackButton = false;
			}
			TMP_Text componentInChildren = ((Component)button).GetComponentInChildren<TMP_Text>(true);
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				return;
			}
			LanguageTextMeshController component = ((Component)componentInChildren).GetComponent<LanguageTextMeshController>();
			if (tokenized && Object.op_Implicit((Object)(object)component))
			{
				((Behaviour)component).enabled = true;
				component.token = textOrToken;
				return;
			}
			if (Object.op_Implicit((Object)(object)component))
			{
				((Behaviour)component).enabled = false;
			}
			componentInChildren.text = (tokenized ? Language.GetString(textOrToken) : textOrToken);
		}

		private void LoadNativeSettingsStyle()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab").WaitForCompletion();
			settingsStyleTemplate = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren<MPButton>(true) : null);
			if (Object.op_Implicit((Object)(object)settingsStyleTemplate))
			{
				Plugin.Log.LogDebug((object)"Using native settings button style from 'RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab'.");
			}
			else
			{
				Plugin.Log.LogWarning((object)"Could not find an MPButton in 'RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab'; using the neutral settings fallback.");
			}
			GameObject val2 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/Generic UI/Prefab/SettingsSubPanel.prefab").WaitForCompletion();
			settingsPanelStyleTemplate = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<Image>() : null);
		}

		private void ApplyNativePanelStyle(Image targetImage)
		{
			//IL_0039: 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)
			Image val = settingsPanelStyleTemplate;
			if (val != null && Object.op_Implicit((Object)(object)val))
			{
				targetImage.sprite = val.sprite;
				targetImage.overrideSprite = val.overrideSprite;
				((Graphic)targetImage).material = ((Graphic)val).material;
				targetImage.type = val.type;
				targetImage.preserveAspect = val.preserveAspect;
				targetImage.fillCenter = val.fillCenter;
				targetImage.pixelsPerUnitMultiplier = val.pixelsPerUnitMultiplier;
				((Graphic)targetImage).color = ((Graphic)val).color;
			}
		}

		private void ApplyNativeSettingsStyle(MPButton button)
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0032: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			MPButton val = settingsStyleTemplate;
			Image[] componentsInChildren;
			if (val != null && Object.op_Implicit((Object)(object)val))
			{
				((Selectable)button).transition = ((Selectable)val).transition;
				((Selectable)button).colors = ((Selectable)val).colors;
				((Selectable)button).spriteState = ((Selectable)val).spriteState;
				((Selectable)button).animationTriggers = ((Selectable)val).animationTriggers;
				Graphic targetGraphic = ((Selectable)val).targetGraphic;
				Image val2 = (Image)(object)((targetGraphic is Image) ? targetGraphic : null);
				if (val2 != null)
				{
					Graphic targetGraphic2 = ((Selectable)button).targetGraphic;
					Image val3 = (Image)(object)((targetGraphic2 is Image) ? targetGraphic2 : null);
					if (val3 != null)
					{
						val3.sprite = val2.sprite;
						val3.overrideSprite = val2.overrideSprite;
						((Graphic)val3).material = ((Graphic)val2).material;
						val3.type = val2.type;
						val3.preserveAspect = val2.preserveAspect;
						val3.fillCenter = val2.fillCenter;
						val3.pixelsPerUnitMultiplier = val2.pixelsPerUnitMultiplier;
						((Graphic)val3).color = ((Graphic)val2).color;
						componentsInChildren = ((Component)button).GetComponentsInChildren<Image>(true);
						foreach (Image val4 in componentsInChildren)
						{
							if ((Object)(object)val4 != (Object)(object)val3)
							{
								((Behaviour)val4).enabled = false;
							}
						}
						return;
					}
				}
			}
			ColorBlock colors = ((Selectable)button).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(0.2f, 0.25f, 0.27f, 1f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.34f, 0.48f, 0.53f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.12f, 0.18f, 0.21f, 1f);
			((ColorBlock)(ref colors)).selectedColor = new Color(0.31f, 0.43f, 0.48f, 1f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.13f, 0.15f, 0.16f, 0.72f);
			((ColorBlock)(ref colors)).colorMultiplier = 1f;
			((Selectable)button).colors = colors;
			Graphic targetGraphic3 = ((Selectable)button).targetGraphic;
			Image val5 = (Image)(object)((targetGraphic3 is Image) ? targetGraphic3 : null);
			if (val5 == null)
			{
				return;
			}
			val5.sprite = null;
			val5.overrideSprite = null;
			((Graphic)val5).color = Color.white;
			componentsInChildren = ((Component)button).GetComponentsInChildren<Image>(true);
			foreach (Image val6 in componentsInChildren)
			{
				if ((Object)(object)val6 != (Object)(object)val5)
				{
					((Behaviour)val6).enabled = false;
				}
			}
		}

		private void OpenPanel()
		{
			//IL_009b: 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_00b3: 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_00d5: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser localNetworkUser = GetLocalNetworkUser();
			if (NetworkServer.active && localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser) && PvPTeamManager.TryGetLobbySelection(localNetworkUser, out var teamId))
			{
				localLobbySelection = teamId;
			}
			Plugin.Log.LogInfo((object)"Opening Resonators of the Soul lobby settings panel.");
			overlayObject.transform.SetAsLastSibling();
			overlayObject.SetActive(true);
			ResonatorModules.RequestSync();
			RefreshPvPTabAvailability(force: true);
			if (IsPvPConfigurationAvailable())
			{
				PvPStartingLoadoutManager.RequestSync();
			}
			ShowPage(0);
			RefreshValues();
			if (IsPvPConfigurationAvailable())
			{
				RefreshTeamPage();
			}
			Canvas.ForceUpdateCanvases();
			ManualLogSource log = Plugin.Log;
			Rect rect = overlayRect.rect;
			object arg = ((Rect)(ref rect)).width;
			rect = overlayRect.rect;
			string text = $"Resonators of the Soul settings panel active: overlay={arg:0}x{((Rect)(ref rect)).height:0}, ";
			rect = panelRect.rect;
			object arg2 = ((Rect)(ref rect)).width;
			rect = panelRect.rect;
			log.LogDebug((object)(text + $"panel={arg2:0}x{((Rect)(ref rect)).height:0}."));
		}

		private void ShowPage(int requestedPage)
		{
			int num = Math.Clamp(requestedPage, 0, 4);
			bool flag = IsPvPConfigurationAvailable();
			if (num != 0 && !flag)
			{
				num = 0;
			}
			else if (!NetworkServer.active && (num == 1 || num == 2))
			{
				num = 0;
			}
			currentPage = num;
			modulesPageObject.SetActive(currentPage == 0);
			modePageObject.SetActive(currentPage == 1);
			rulesPageObject.SetActive(currentPage == 2);
			teamsPageObject.SetActive(currentPage == 3);
			loadoutPageObject.SetActive(currentPage == 4);
			HGTextMeshProUGUI val = pageHintText;
			string text = ((currentPage != 0) ? Language.GetString(currentPage switch
			{
				1 => "WATERBUCKET_PVP_SETTINGS_MODE_HINT", 
				2 => "WATERBUCKET_PVP_SETTINGS_HINT", 
				3 => "WATERBUCKET_PVP_SETTINGS_TEAM_HINT", 
				_ => "WATERBUCKET_PVP_LOADOUT_HINT", 
			}) : (NetworkServer.active ? "选择本房间启用的功能模块;设置会同步给所有玩家。" : "当前显示房主同步的模块设置;只有房主可以修改。"));
			((TMP_Text)val).text = text;
			((Selectable)modulesTabButton).interactable = true;
			((Selectable)modeTabButton).interactable = flag && NetworkServer.active;
			((Selectable)rulesTabButton).interactable = flag && NetworkServer.active;
			((Selectable)teamsTabButton).interactable = flag;
			((Selectable)loadoutTabButton).interactable = flag;
			SetTabVisual(modulesTabButton, currentPage == 0);
			SetTabVisual(modeTabButton, currentPage == 1);
			SetTabVisual(rulesTabButton, currentPage == 2);
			SetTabVisual(teamsTabButton, currentPage == 3);
			SetTabVisual(loadoutTabButton, currentPage == 4);
			if (currentPage == 0)
			{
				RefreshValues();
				((Selectable)modulesTabButton).Select();
			}
			else if (currentPage == 1 || currentPage == 2)
			{
				RefreshValues();
				((Selectable)((currentPage == 1) ? modeTabButton : rulesTabButton)).Select();
			}
			else if (currentPage == 3)
			{
				RefreshTeamPage();
				MPButton item = teamButtons.FirstOrDefault<(MPButton, int)>(((MPButton Button, int TeamId) entry) => entry.TeamId == localLobbySelection).Item1;
				if (item != null)
				{
					((Selectable)item).Select();
				}
			}
			else
			{
				PvPStartingLoadoutManager.RequestSync();
				RefreshLoadoutPage();
				((Selectable)loadoutTabButton).Select();
			}
		}

		private void RefreshPvPTabAvailability(bool force)
		{
			if (!Object.op_Implicit((Object)(object)modulesTabButton))
			{
				return;
			}
			bool flag = IsPvPConfigurationAvailable();
			if (force || flag != wasPvPConfigurationAvailable)
			{
				wasPvPConfigurationAvailable = flag;
				((Component)modeTabButton).gameObject.SetActive(flag);
				((Component)rulesTabButton).gameObject.SetActive(flag);
				((Component)teamsTabButton).gameObject.SetActive(flag);
				((Component)loadoutTabButton).gameObject.SetActive(flag);
				if (!flag && currentPage != 0)
				{
					ShowPage(0);
					return;
				}
				((Selectable)modeTabButton).interactable = flag && NetworkServer.active;
				((Selectable)rulesTabButton).interactable = flag && NetworkServer.active;
				((Selectable)teamsTabButton).interactable = flag;
				((Selectable)loadoutTabButton).interactable = flag;
			}
		}

		private static void SetTabVisual(MPButton button, bool selected)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text componentInChildren = ((Component)button).GetComponentInChildren<TMP_Text>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.fontStyle = (FontStyles)(selected ? 1 : 0);
				((Graphic)componentInChildren).color = (selected ? new Color(1f, 0.72f, 0.28f, 1f) : new Color(0.78f, 0.86f, 0.9f, 1f));
			}
		}

		private void ChooseTeam(int teamId)
		{
			NetworkUser localNetworkUser = GetLocalNetworkUser();
			if (localNetworkUser == null || !Object.op_Implicit((Object)(object)localNetworkUser) || !IsPvPModeSelected())
			{
				return;
			}
			NetworkUser val = localNetworkUser;
			if (NetworkServer.active)
			{
				if (!PvPTeamManager.SetLobbySelection(val, teamId))
				{
					return;
				}
			}
			else
			{
				string text = "WATERBUCKET_PVP_TEAM:" + teamId;
				Console.instance.SubmitCmd(val, "say \"" + text + "\"", false);
			}
			localLobbySelection = teamId;
			RefreshTeamPage();
		}

		private void RefreshTeamPage()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)currentChoiceText) || !Object.op_Implicit((Object)(object)rosterText))
			{
				return;
			}
			NetworkUser localNetworkUser = GetLocalNetworkUser();
			if (NetworkServer.active && localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser))
			{
				localLobbySelection = (PvPTeamManager.TryGetLobbySelection(localNetworkUser, out var teamId) ? teamId : (-1));
			}
			((TMP_Text)currentChoiceText).text = Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_CURRENT") + ":" + GetTeamButtonText(localLobbySelection);
			foreach (var teamButton in teamButtons)
			{
				MPButton item = teamButton.Button;
				int item2 = teamButton.TeamId;
				bool flag = item2 == localLobbySelection;
				TMP_Text componentInChildren = ((Component)item).GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.text = (flag ? ("◆  " + GetTeamButtonText(item2)) : GetTeamButtonText(item2));
					componentInChildren.fontStyle = (FontStyles)(flag ? 1 : 0);
					((Graphic)componentInChildren).color = (flag ? Color.white : GetTeamColor(item2));
				}
			}
			List<string> list = new List<string>();
			foreach (NetworkUser item3 in NetworkUser.readOnlyInstancesList.Where((NetworkUser user) => Object.op_Implicit((Object)(object)user)).OrderBy<NetworkUser, string>((NetworkUser user) => user.userName, StringComparer.CurrentCultureIgnoreCase))
			{
				int teamId2 = -1;
				bool flag2 = false;
				if (NetworkServer.active)
				{
					flag2 = PvPTeamManager.TryGetLobbySelection(item3, out teamId2);
				}
				else if (Object.op_Implicit((Object)(object)localNetworkUser) && (Object)(object)item3 == (Object)(object)localNetworkUser)
				{
					teamId2 = localLobbySelection;
					flag2 = teamId2 >= 0;
				}
				string text = (flag2 ? Language.GetString(PvPTeamRegistry.GetTeamNameToken(teamId2)) : Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_PENDING"));
				string text2 = ((Object.op_Implicit((Object)(object)localNetworkUser) && (Object)(object)item3 == (Object)(object)localNetworkUser) ? "◆" : "•");
				list.Add(text2 + "  " + EscapeRichText(item3.userName) + "    <color=#79CBE8>" + text + "</color>");
			}
			((TMP_Text)rosterText).text = ((list.Count > 0) ? string.Join("\n", list) : "—");
		}

		private void ClosePanel()
		{
			if (Object.op_Implicit((Object)(object)overlayObject))
			{
				overlayObject.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)openButtonObject))
			{
				MPButton component = openButtonObject.GetComponent<MPButton>();
				if (Object.op_Implicit((Object)(object)component))
				{
					((Selectable)component).Select();
				}
			}
		}

		private void RefreshValues()
		{
			for (int i = 0; i < valueRefreshers.Count; i++)
			{
				valueRefreshers[i]();
			}
		}

		private static NetworkUser? GetLocalNetworkUser()
		{
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			if (firstLocalUser == null)
			{
				return null;
			}
			return firstLocalUser.currentNetworkUser;
		}

		private static string GetTeamButtonText(int teamId)
		{
			if (teamId >= 0)
			{
				return Language.GetString(PvPTeamRegistry.GetTeamNameToken(teamId));
			}
			return Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_AUTO");
		}

		private static string GetMatchModeText()
		{
			return Language.GetString(PvPConfig.CurrentMatchMode switch
			{
				PvPConfig.MatchModeKind.Unlimited => "WATERBUCKET_PVP_SETTINGS_MATCH_UNLIMITED", 
				PvPConfig.MatchModeKind.TimedKills => "WATERBUCKET_PVP_SETTINGS_MATCH_TIMED", 
				_ => "WATERBUCKET_PVP_SETTINGS_MATCH_LIMITED", 
			});
		}

		private static string GetLoadoutCategoryToken(StartingLoadoutCategory category)
		{
			return category switch
			{
				StartingLoadoutCategory.White => "WATERBUCKET_PVP_LOADOUT_WHITE", 
				StartingLoadoutCategory.Green => "WATERBUCKET_PVP_LOADOUT_GREEN", 
				StartingLoadoutCategory.Yellow => "WATERBUCKET_PVP_LOADOUT_YELLOW", 
				StartingLoadoutCategory.Orange => "WATERBUCKET_PVP_LOADOUT_ORANGE", 
				StartingLoadoutCategory.Red => "WATERBUCKET_PVP_LOADOUT_RED", 
				StartingLoadoutCategory.Blue => "WATERBUCKET_PVP_LOADOUT_BLUE", 
				StartingLoadoutCategory.VoidWhite => "WATERBUCKET_PVP_LOADOUT_VOID_WHITE", 
				StartingLoadoutCategory.VoidGreen => "WATERBUCKET_PVP_LOADOUT_VOID_GREEN", 
				StartingLoadoutCategory.VoidRed => "WATERBUCKET_PVP_LOADOUT_VOID_RED", 
				_ => string.Empty, 
			};
		}

		private static void CycleMatchMode(int direction)
		{
			PvPConfig.MatchModeKind currentMatchMode = PvPConfig.CurrentMatchMode;
			int length = Enum.GetValues(typeof(PvPConfig.MatchModeKind)).Length;
			int num = (int)(currentMatchMode + direction) % length;
			if (num < 0)
			{
				num += length;
			}
			ConfigEntry<string> matchMode = PvPConfig.MatchMode;
			PvPConfig.MatchModeKind matchModeKind = (PvPConfig.MatchModeKind)num;
			matchMode.Value = matchModeKind.ToString();
		}

		private static Color GetTeamColor(int teamId)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0037: 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_0052: 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_006d: 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 referen