Decompiled source of ResonatorsOfTheSoul v0.75.0

ResonatorsOfTheSoul.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.BrotherHaunt;
using EntityStates.BrotherMonster;
using EntityStates.BrotherMonster.Weapon;
using EntityStates.Commando.CommandoWeapon;
using EntityStates.ComputationalExchange;
using EntityStates.Drifter;
using EntityStates.FalseSon;
using EntityStates.FalseSonBoss;
using EntityStates.GameOver;
using EntityStates.Interactables.GoldBeacon;
using EntityStates.IronHauler.Weapon;
using EntityStates.Loader;
using EntityStates.LunarTeleporter;
using EntityStates.MeridianEvent;
using EntityStates.Missions.BrotherEncounter;
using EntityStates.PrimeMeridian;
using EntityStates.Railgunner.Reload;
using EntityStates.Railgunner.Scope;
using EntityStates.Railgunner.Weapon;
using EntityStates.Seeker;
using EntityStates.ShrineRebirth;
using EntityStates.SolusHeart;
using EntityStates.SolusHeart.Death;
using EntityStates.SolusHeart.Giant;
using EntityStates.SolusVendorShrine;
using EntityStates.SolusWing;
using EntityStates.SolusWing2;
using EntityStates.TitanMonster;
using EntityStates.VoidCamp;
using EntityStates.VoidRaidCrab;
using EntityStates.VoidRaidCrab.Weapon;
using HG;
using HG.BlendableTypes;
using HG.GeneralSerializer;
using HurricaneDifficulty;
using HurricaneDifficulty.Config;
using HurricaneDifficulty.Debugging;
using HurricaneDifficulty.DuelPantheon;
using HurricaneDifficulty.Modules;
using HurricaneDifficulty.Pantheon;
using HurricaneDifficulty.Routes;
using IL;
using IL.EntityStates;
using IL.EntityStates.Bell.BellWeapon;
using IL.EntityStates.BrotherMonster;
using IL.EntityStates.FalseSon;
using IL.EntityStates.FalseSonBoss;
using IL.EntityStates.FlyingVermin.Weapon;
using IL.EntityStates.SolusHeart.Death;
using IL.RoR2;
using IL.RoR2.Artifacts;
using IL.RoR2.UI;
using KinematicCharacterController;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On.EntityStates.BrotherMonster;
using On.EntityStates.Drifter;
using On.EntityStates.GameOver;
using On.EntityStates.IronHauler.Weapon;
using On.EntityStates.MeridianEvent;
using On.EntityStates.Missions.BrotherEncounter;
using On.EntityStates.PrimeMeridian;
using On.EntityStates.Railgunner.Reload;
using On.EntityStates.Seeker;
using On.EntityStates.SolusHeart;
using On.EntityStates.SolusHeart.Death;
using On.EntityStates.SolusHeart.Giant;
using On.EntityStates.TitanMonster;
using On.EntityStates.VoidCamp;
using On.EntityStates.VoidRaidCrab;
using On.EntityStates.VoidRaidCrab.Weapon;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.CharacterAI;
using On.RoR2.CharacterSpeech;
using On.RoR2.ExpansionManagement;
using On.RoR2.Orbs;
using On.RoR2.Projectile;
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.Achievements.Artifacts;
using RoR2.AddressableAssets;
using RoR2.Audio;
using RoR2.CameraModes;
using RoR2.CharacterAI;
using RoR2.CharacterSpeech;
using RoR2.ConVar;
using RoR2.ContentManagement;
using RoR2.ExpansionManagement;
using RoR2.HudOverlay;
using RoR2.Items;
using RoR2.Navigation;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Scripts.GameBehaviors;
using RoR2.Skills;
using RoR2.SolusWeb;
using RoR2.SolusWingGrid;
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.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
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.75.0.0")]
[assembly: AssemblyInformationalVersion("0.75.0+87e5bebabbf14ce303bb3547907cd19b83102784")]
[assembly: AssemblyProduct("ResonatorsOfTheSoul")]
[assembly: AssemblyTitle("ResonatorsOfTheSoul")]
[assembly: AssemblyVersion("0.75.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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 => IsPvPModeRun(Run.instance);

		internal static bool IsPvPModeRun(Run? run)
		{
			if (!ResonatorModules.PvPActive || run == null || !Object.op_Implicit((Object)(object)run))
			{
				return false;
			}
			return Object.op_Implicit((Object)(object)((Component)run).GetComponent<PvPModeRunMarker>());
		}

		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 sealed class PvPLobbySettingsPanel : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<string, string> <>9__15_0;

			public static Action <>9__50_1;

			public static Action <>9__50_2;

			public static Func<string> <>9__50_3;

			public static Action <>9__50_4;

			public static Action <>9__50_5;

			public static Func<string> <>9__50_6;

			public static Action <>9__50_7;

			public static Action <>9__50_8;

			public static Func<int> <>9__50_9;

			public static Func<int> <>9__50_10;

			public static Func<int> <>9__50_11;

			public static Func<int> <>9__50_12;

			public static Func<float> <>9__50_13;

			public static Func<float> <>9__50_14;

			public static Func<float> <>9__50_15;

			public static Func<float> <>9__50_16;

			public static Func<int> <>9__50_17;

			public static Func<int> <>9__50_18;

			public static Func<int> <>9__50_19;

			public static Func<NetworkUser, string> <>9__57_0;

			public static UnityAction <>9__61_0;

			public static Action <>9__124_0;

			public static Action <>9__124_1;

			public static Func<int> <>9__124_2;

			public static Func<int> <>9__124_3;

			public static Func<string> <>9__124_4;

			public static Action <>9__124_5;

			public static Func<int> <>9__124_6;

			public static Func<string> <>9__124_7;

			public static Action <>9__124_8;

			public static Func<float> <>9__124_9;

			public static Action<float> <>9__124_10;

			public static Func<float> <>9__124_11;

			public static Func<string> <>9__124_12;

			public static Action <>9__124_13;

			public static Func<float, string> <>9__125_0;

			public static Func<float, string> <>9__125_1;

			public static Func<float, string> <>9__125_2;

			public static Func<float, string> <>9__125_3;

			public static Func<float, string> <>9__125_4;

			public static Func<float, string> <>9__125_5;

			public static Func<float, string> <>9__125_6;

			public static Func<NetworkUser, bool> <>9__159_0;

			public static Func<NetworkUser, string> <>9__159_1;

			internal string <RefreshChimera>b__15_0(string key)
			{
				object obj;
				if (key.Length != 0)
				{
					obj = ChimeraCatalog.FindSkill(key)?.Name;
					if (obj == null)
					{
						return "缺失技能";
					}
				}
				else
				{
					obj = "基底原生";
				}
				return (string)obj;
			}

			internal void <CreateExtraPages>b__50_1()
			{
				CycleBossPlayer(-1);
			}

			internal void <CreateExtraPages>b__50_2()
			{
				CycleBossPlayer(1);
			}

			internal string <CreateExtraPages>b__50_3()
			{
				return DuelModule.BodyName(CurrentDuel.BossBody);
			}

			internal void <CreateExtraPages>b__50_4()
			{
				Cycle(DuelConfig.BossBody, DuelModule.BossNames.Where(DuelModule.ValidBody).ToArray(), -1);
			}

			internal void <CreateExtraPages>b__50_5()
			{
				Cycle(DuelConfig.BossBody, DuelModule.BossNames.Where(DuelModule.ValidBody).ToArray(), 1);
			}

			internal string <CreateExtraPages>b__50_6()
			{
				return Language.GetString(DuelModule.Scene(CurrentDuel.Map).nameToken);
			}

			internal void <CreateExtraPages>b__50_7()
			{
				Cycle(DuelConfig.Map, DuelModule.MapNames, -1);
			}

			internal void <CreateExtraPages>b__50_8()
			{
				Cycle(DuelConfig.Map, DuelModule.MapNames, 1);
			}

			internal int <CreateExtraPages>b__50_9()
			{
				return CurrentDuel.ChallengerLevel;
			}

			internal int <CreateExtraPages>b__50_10()
			{
				return CurrentDuel.BossLevel;
			}

			internal int <CreateExtraPages>b__50_11()
			{
				return CurrentDuel.ChallengerPoints;
			}

			internal int <CreateExtraPages>b__50_12()
			{
				return CurrentDuel.BossPoints;
			}

			internal float <CreateExtraPages>b__50_13()
			{
				return CurrentDuel.ChallengerHealth;
			}

			internal float <CreateExtraPages>b__50_14()
			{
				return CurrentDuel.ChallengerDamage;
			}

			internal float <CreateExtraPages>b__50_15()
			{
				return CurrentDuel.BossHealth;
			}

			internal float <CreateExtraPages>b__50_16()
			{
				return CurrentDuel.BossDamage;
			}

			internal int <CreateExtraPages>b__50_17()
			{
				return CurrentDuel.Countdown;
			}

			internal int <CreateExtraPages>b__50_18()
			{
				return CurrentDuel.TimeLimitMinutes;
			}

			internal int <CreateExtraPages>b__50_19()
			{
				return CurrentDuel.SpawnDistance;
			}

			internal string <CycleBossPlayer>b__57_0(NetworkUser user)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				return ((object)user.id/*cast due to .constrained prefix*/).ToString();
			}

			internal void <BuildDebugPage>b__61_0()
			{
				DebugCharacterModule.Request("");
			}

			internal void <CreateModePage>b__124_0()
			{
				CycleMatchMode(-1);
			}

			internal void <CreateModePage>b__124_1()
			{
				CycleMatchMode(1);
			}

			internal int <CreateModePage>b__124_2()
			{
				return 99;
			}

			internal int <CreateModePage>b__124_3()
			{
				return 120;
			}

			internal string <CreateModePage>b__124_4()
			{
				if (!PvPConfig.IsFfa)
				{
					return Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_MODE");
				}
				return "FFA";
			}

			internal void <CreateModePage>b__124_5()
			{
				PvPConfig.AssignmentMode.Value = (PvPConfig.IsFfa ? "Team" : "FFA");
			}

			internal int <CreateModePage>b__124_6()
			{
				return Math.Max(2, PvPTeamRegistry.Count);
			}

			internal string <CreateModePage>b__124_7()
			{
				return BoolText(PvPConfig.FriendlyFire.Value);
			}

			internal void <CreateModePage>b__124_8()
			{
				PvPConfig.FriendlyFire.Value = !PvPConfig.FriendlyFire.Value;
			}

			internal float <CreateModePage>b__124_9()
			{
				return PvPConfig.CurrentRespawnDelaySeconds;
			}

			internal void <CreateModePage>b__124_10(float value)
			{
				if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives)
				{
					PvPConfig.LimitedLivesRespawnDelaySeconds.Value = value;
				}
				else
				{
					PvPConfig.RespawnDelaySeconds.Value = value;
				}
			}

			internal float <CreateModePage>b__124_11()
			{
				if (PvPConfig.CurrentMatchMode != PvPConfig.MatchModeKind.LimitedLives)
				{
					return 60f;
				}
				return 180f;
			}

			internal string <CreateModePage>b__124_12()
			{
				return Language.GetString(PvPConfig.StageFiveDefaultsToLoop ? "WATERBUCKET_PVP_SETTINGS_ROUTE_LOOP" : "WATERBUCKET_PVP_SETTINGS_ROUTE_MOON");
			}

			internal void <CreateModePage>b__124_13()
			{
				PvPConfig.StageFiveRoute.Value = (PvPConfig.StageFiveDefaultsToLoop ? "Moon" : "Loop");
			}

			internal string <CreateRulesPage>b__125_0(float value)
			{
				return $"×{value:0.00}";
			}

			internal string <CreateRulesPage>b__125_1(float value)
			{
				return $"×{value:0.00}";
			}

			internal string <CreateRulesPage>b__125_2(float value)
			{
				return $"×{value:0.00}";
			}

			internal string <CreateRulesPage>b__125_3(float value)
			{
				return $"×{value:0.00}";
			}

			internal string <CreateRulesPage>b__125_4(float value)
			{
				return $"×{value:0.00}";
			}

			internal string <CreateRulesPage>b__125_5(float value)
			{
				return $"{value:0} m";
			}

			internal string <CreateRulesPage>b__125_6(float value)
			{
				return $"{value:0.#} m";
			}

			internal bool <RefreshTeamPage>b__159_0(NetworkUser user)
			{
				return Object.op_Implicit((Object)(object)user);
			}

			internal string <RefreshTeamPage>b__159_1(NetworkUser user)
			{
				return user.userName;
			}
		}

		private const int ChimeraPage = 8;

		private GameObject chimeraPageObject;

		private MPButton chimeraTabButton;

		private HGTextMeshProUGUI chimeraSummary;

		private HGTextMeshProUGUI chimeraDetails;

		private HGTextMeshProUGUI chimeraPageLabel;

		private Transform chimeraGrid;

		private int chimeraSlot = -1;

		private int chimeraPage;

		private string chimeraSearch = "";

		private const int CommandPage = 7;

		private GameObject commandPageObject;

		private MPButton commandTabButton;

		private TMP_InputField commandInput;

		private HGTextMeshProUGUI commandStatus;

		private HGTextMeshProUGUI commandFeedback;

		private string displayedCommandRule = "";

		private TMP_InputField debugSizeInput;

		private HGTextMeshProUGUI debugSizeHint;

		private Transform debugSizeRow;

		private float displayedDebugSize = -1f;

		private const int DuelPage = 5;

		private const int DebugCharacterPage = 6;

		private GameObject duelPageObject;

		private GameObject debugPageObject;

		private MPButton duelTabButton;

		private MPButton debugTabButton;

		private HGTextMeshProUGUI debugSelection;

		private HGTextMeshProUGUI debugPageLabel;

		private Transform debugGrid;

		private int debugPage;

		private string debugSearch = "";

		private float nextExtraRefresh;

		private GameObject duelBasic;

		private GameObject duelAdvanced;

		private bool advanced;

		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 static MPButton? settingsStyleTemplate;

		private static 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 static DuelSettings CurrentDuel
		{
			get
			{
				if (!NetworkServer.active)
				{
					return DuelNetwork.Settings;
				}
				return DuelConfig.Snapshot();
			}
		}

		private static bool CanEditDuel
		{
			get
			{
				if (NetworkServer.active)
				{
					return !Object.op_Implicit((Object)(object)Run.instance);
				}
				return false;
			}
		}

		private void CreateChimeraPage(Transform parent)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Expected O, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Expected O, but got Unknown
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Expected O, but got Unknown
			chimeraPageObject = CreatePage(parent, "Chimera", 490f);
			Transform transform = chimeraPageObject.transform;
			chimeraSummary = CreateText(transform, "", 17f, (FontStyles)0, (TextAlignmentOptions)514, 68f, tokenized: false);
			Transform parent2 = CreateRow(transform);
			((UnityEvent)((Button)CloneButton(parent2, "选择基底", tokenized: false, -1f, 35f)).onClick).AddListener((UnityAction)delegate
			{
				SelectChimeraSlot(-1);
			});
			for (int num = 0; num < 4; num++)
			{
				int slot = num;
				((UnityEvent)((Button)CloneButton(parent2, ChimeraCatalog.SlotNames[num], tokenized: false, -1f, 35f)).onClick).AddListener((UnityAction)delegate
				{
					SelectChimeraSlot(slot);
				});
			}
			Transform val = CreateRow(transform);
			((UnityEvent)((Button)CloneButton(val, "此槽沿用基底技能", tokenized: false, 210f, 35f)).onClick).AddListener((UnityAction)delegate
			{
				if (chimeraSlot >= 0)
				{
					ChimeraNetwork.Edit(null, chimeraSlot, "");
					RefreshChimera();
				}
			});
			GameObject val2 = new GameObject("Search", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField),
				typeof(LayoutElement)
			});
			val2.layer = ((Component)parent).gameObject.layer;
			val2.transform.SetParent(val, false);
			val2.GetComponent<LayoutElement>().flexibleWidth = 1f;
			((Graphic)val2.GetComponent<Image>()).color = new Color(0.08f, 0.12f, 0.16f);
			HGTextMeshProUGUI val3 = CreateText(val2.transform, "", 17f, (FontStyles)0, (TextAlignmentOptions)4097, 35f, tokenized: false);
			Stretch((RectTransform)((TMP_Text)val3).transform);
			TMP_InputField component = val2.GetComponent<TMP_InputField>();
			component.textViewport = (RectTransform)val2.transform;
			component.textComponent = (TMP_Text)(object)val3;
			HGTextMeshProUGUI val4 = CreateText(val2.transform, "搜索角色或技能名称", 17f, (FontStyles)2, (TextAlignmentOptions)4097, 35f, tokenized: false);
			Stretch((RectTransform)((TMP_Text)val4).transform);
			((Graphic)val4).color = Color.gray;
			component.placeholder = (Graphic)(object)val4;
			((UnityEvent<string>)(object)component.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
			{
				chimeraSearch = value;
				chimeraPage = 0;
				RebuildChimera();
			});
			chimeraGrid = CreatePage(transform, "ChoiceGrid", 182f).transform;
			Transform parent3 = CreateRow(transform);
			MPButton val5 = CloneButton(parent3, "上一页", tokenized: false, 130f, 32f);
			chimeraPageLabel = CreateText(parent3, "", 16f, (FontStyles)0, (TextAlignmentOptions)514, 32f, tokenized: false);
			((Component)chimeraPageLabel).GetComponent<LayoutElement>().flexibleWidth = 1f;
			MPButton obj = CloneButton(parent3, "下一页", tokenized: false, 130f, 32f);
			((UnityEvent)((Button)val5).onClick).AddListener((UnityAction)delegate
			{
				chimeraPage--;
				RebuildChimera();
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				chimeraPage++;
				RebuildChimera();
			});
			chimeraDetails = CreateText(transform, "", 15f, (FontStyles)0, (TextAlignmentOptions)4097, 100f, tokenized: false);
			RefreshChimera();
			RebuildChimera();
		}

		private void SelectChimeraSlot(int slot)
		{
			chimeraSlot = slot;
			chimeraPage = 0;
			RebuildChimera();
		}

		private bool ChimeraMatches(string text)
		{
			return text.IndexOf(chimeraSearch, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private void RebuildChimera()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)chimeraGrid))
			{
				return;
			}
			foreach (Transform item in chimeraGrid)
			{
				((Component)item).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			GameObject[] array = ChimeraCatalog.Bodies.Where((GameObject b) => ChimeraMatches(ChimeraCatalog.BodyName(b)) || ChimeraMatches(((Object)b).name)).ToArray();
			ChimeraCatalog.Skill[] array2 = ChimeraCatalog.Skills.Where((ChimeraCatalog.Skill s) => ChimeraMatches(s.Label) || ChimeraMatches(s.Key)).ToArray();
			int num = ((chimeraSlot < 0) ? array.Length : array2.Length);
			int num2 = Math.Max(1, (num + 6 - 1) / 6);
			chimeraPage = (chimeraPage % num2 + num2) % num2;
			((TMP_Text)chimeraPageLabel).text = string.Format("{0} · {1}/{2} · {3} 项", (chimeraSlot < 0) ? "基底" : ChimeraCatalog.SlotNames[chimeraSlot], chimeraPage + 1, num2, num);
			Transform parent = chimeraGrid;
			for (int num3 = chimeraPage * 6; num3 < Math.Min(num, (chimeraPage + 1) * 6); num3++)
			{
				if (num3 % 2 == 0)
				{
					parent = CreateRow(chimeraGrid);
				}
				if (chimeraSlot < 0)
				{
					GameObject selected = array[num3];
					MPButton obj = CloneButton(parent, ChimeraCatalog.BodyName(selected), tokenized: false, -1f, 48f);
					((Selectable)obj).interactable = !Object.op_Implicit((Object)(object)Run.instance);
					((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
					{
						ChimeraNetwork.Edit(((Object)selected).name);
						RefreshChimera();
						((TMP_Text)chimeraDetails).text = ChimeraCatalog.Passive(selected);
					});
					AddChimeraTooltip(obj, ChimeraCatalog.BodyName(selected), ChimeraCatalog.Passive(selected));
					continue;
				}
				ChimeraCatalog.Skill selected2 = array2[num3];
				MPButton obj2 = CloneButton(parent, selected2.Name + "\n<size=12>" + ChimeraCatalog.BodyName(selected2.Body) + " · " + ChimeraCatalog.SlotNames[selected2.Slot] + "</size>", tokenized: false, -1f, 48f);
				((Selectable)obj2).interactable = !Object.op_Implicit((Object)(object)Run.instance);
				((UnityEvent)((Button)obj2).onClick).AddListener((UnityAction)delegate
				{
					ChimeraNetwork.Edit(null, chimeraSlot, selected2.Key);
					RefreshChimera();
					((TMP_Text)chimeraDetails).text = Language.GetString(selected2.Def.skillDescriptionToken) + "\n" + ChimeraCompatibility.Note(ChimeraNetwork.Local.Body, selected2);
				});
				AddChimeraTooltip(obj2, selected2.Label, Language.GetString(selected2.Def.skillDescriptionToken) + "\n\n" + ChimeraCompatibility.Note(ChimeraNetwork.Local.Body, selected2));
			}
		}

		private static void AddChimeraTooltip(MPButton button, string title, string description)
		{
			TooltipProvider obj = ((Component)button).GetComponent<TooltipProvider>() ?? ((Component)button).gameObject.AddComponent<TooltipProvider>();
			obj.overrideTitleText = title;
			obj.overrideBodyText = description;
		}

		private void RefreshChimera()
		{
			if (!Object.op_Implicit((Object)(object)chimeraSummary))
			{
				return;
			}
			ChimeraSelection local = ChimeraNetwork.Local;
			GameObject val = ChimeraCatalog.FindBody(local.Body);
			string[] array = local.Skills.Select(delegate(string key)
			{
				object obj;
				if (key.Length != 0)
				{
					obj = ChimeraCatalog.FindSkill(key)?.Name;
					if (obj == null)
					{
						return "缺失技能";
					}
				}
				else
				{
					obj = "基底原生";
				}
				return (string)obj;
			}).ToArray();
			((TMP_Text)chimeraSummary).text = "基底:" + (Object.op_Implicit((Object)(object)val) ? ChimeraCatalog.BodyName(val) : local.Body) + "\nM1:" + array[0] + "\u3000 M2:" + array[1] + "\nShift:" + array[2] + "\u3000 R:" + array[3];
			if (currentPage == 8)
			{
				((TMP_Text)pageHintText).text = "选择奇美拉角色后生效;每位玩家独立配置,开局锁定。 " + ChimeraNetwork.Feedback;
			}
		}

		private void CreateCommandPage(Transform parent)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			commandPageObject = CreatePage(parent, "CommandDetails", 470f);
			Transform transform = commandPageObject.transform;
			CreateSectionHeader(transform, "统率神器 · 生效层数", tokenized: false);
			commandStatus = CreateText(transform, "", 19f, (FontStyles)1, (TextAlignmentOptions)514, 42f, tokenized: false);
			CreateText(transform, "先在大厅开启统率神器,再由房主修改。未指定的层数不启用统率。", 18f, (FontStyles)0, (TextAlignmentOptions)514, 42f, tokenized: false);
			GameObject val = new GameObject("StageSelection", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField),
				typeof(LayoutElement)
			});
			val.layer = ((Component)transform).gameObject.layer;
			val.transform.SetParent(transform, false);
			val.GetComponent<LayoutElement>().preferredHeight = 44f;
			((Graphic)val.GetComponent<Image>()).color = new Color(0.08f, 0.12f, 0.16f);
			HGTextMeshProUGUI val2 = CreateText(val.transform, "", 22f, (FontStyles)0, (TextAlignmentOptions)514, 44f, tokenized: false);
			Stretch((RectTransform)((TMP_Text)val2).transform);
			commandInput = val.GetComponent<TMP_InputField>();
			commandInput.textViewport = (RectTransform)val.transform;
			commandInput.textComponent = (TMP_Text)(object)val2;
			commandInput.characterLimit = 256;
			commandInput.lineType = (LineType)0;
			Transform parent2 = CreateRow(transform);
			((UnityEvent)((Button)CloneButton(parent2, "应用层数", tokenized: false, -1f, 42f)).onClick).AddListener((UnityAction)delegate
			{
				SaveCommandRule(commandInput.text);
			});
			((UnityEvent)((Button)CloneButton(parent2, "恢复全程", tokenized: false, -1f, 42f)).onClick).AddListener((UnityAction)delegate
			{
				SaveCommandRule("*");
			});
			commandFeedback = CreateText(transform, "", 18f, (FontStyles)0, (TextAlignmentOptions)514, 35f, tokenized: false);
			CreateText(transform, "*:全程开启\n1,2:仅第 1、2 层\u3000\u300012:仅第 12 层\n1-5:第 5 层及之前\u3000\u30006+:第 6 层及以后\n可组合填写,例如 1,3-5,10+。", 20f, (FontStyles)0, (TextAlignmentOptions)514, 135f, tokenized: false);
			CreateText(transform, "按游戏原生层数计数,循环后继续累加;隐藏区域也沿用原生计数。\n设置自动保存并同步给所有玩家,开局后本局规则固定。", 17f, (FontStyles)0, (TextAlignmentOptions)514, 65f, tokenized: false);
		}

		private void SaveCommandRule(string expression)
		{
			if (CommandStageModule.CanEdit)
			{
				if (!CommandStageSelection.TryParse(expression, out CommandStageSelection selection))
				{
					((TMP_Text)commandFeedback).text = "格式无效,请填写正整数、范围或 *;原设置保持不变。";
				}
				else if (ResonatorModules.SetHostCommandStages(selection.Expression))
				{
					commandInput.SetTextWithoutNotify(selection.Expression);
					((TMP_Text)commandFeedback).text = "已保存。";
					RefreshCommandPage();
				}
			}
		}

		private void RefreshCommandPage()
		{
			if (Object.op_Implicit((Object)(object)commandInput))
			{
				bool canEdit = CommandStageModule.CanEdit;
				((Selectable)commandInput).interactable = canEdit;
				MPButton[] componentsInChildren = commandPageObject.GetComponentsInChildren<MPButton>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Selectable)componentsInChildren[i]).interactable = canEdit;
				}
				string lobbyCommandStages = ResonatorModules.LobbyCommandStages;
				if (displayedCommandRule != lobbyCommandStages || !canEdit)
				{
					commandInput.SetTextWithoutNotify(lobbyCommandStages);
					displayedCommandRule = lobbyCommandStages;
				}
				((TMP_Text)commandStatus).text = ((!CommandStageModule.LobbyCommandEnabled) ? "统率未开启:请先在大厅启用统率神器。" : ((!ResonatorModules.GetLobbyEnabled(ResonatorModules.ModuleKind.Artifacts)) ? "神器模块已关闭:当前采用原版统率规则。" : ((NetworkServer.active ? "当前设置:" : "房主设置(只读):") + ((lobbyCommandStages == "*") ? "全程开启" : lobbyCommandStages))));
			}
		}

		private void CreateDebugSizeControls(Transform parent)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			debugSizeRow = CreateRow(parent);
			CreateText(debugSizeRow, "本人体型", 18f, (FontStyles)0, (TextAlignmentOptions)514, 36f, tokenized: false);
			MPButton val = CloneButton(debugSizeRow, "−", tokenized: false, 45f, 36f);
			GameObject val2 = new GameObject("BodySize", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField),
				typeof(LayoutElement)
			});
			val2.layer = ((Component)parent).gameObject.layer;
			val2.transform.SetParent(debugSizeRow, false);
			val2.GetComponent<LayoutElement>().flexibleWidth = 1f;
			val2.GetComponent<LayoutElement>().preferredHeight = 36f;
			((Graphic)val2.GetComponent<Image>()).color = new Color(0.08f, 0.12f, 0.16f);
			HGTextMeshProUGUI val3 = CreateText(val2.transform, "1", 20f, (FontStyles)0, (TextAlignmentOptions)514, 36f, tokenized: false);
			Stretch((RectTransform)((TMP_Text)val3).transform);
			debugSizeInput = val2.GetComponent<TMP_InputField>();
			debugSizeInput.textViewport = (RectTransform)val2.transform;
			debugSizeInput.textComponent = (TMP_Text)(object)val3;
			debugSizeInput.characterLimit = 12;
			debugSizeInput.lineType = (LineType)0;
			MPButton val4 = CloneButton(debugSizeRow, "+", tokenized: false, 45f, 36f);
			MPButton val5 = CloneButton(debugSizeRow, "应用", tokenized: false, 85f, 36f);
			MPButton obj = CloneButton(debugSizeRow, "恢复 1 倍", tokenized: false, 130f, 36f);
			((UnityEvent)((Button)val).onClick).AddListener((UnityAction)delegate
			{
				StepDebugSize(-1);
			});
			((UnityEvent)((Button)val4).onClick).AddListener((UnityAction)delegate
			{
				StepDebugSize(1);
			});
			((UnityEvent)((Button)val5).onClick).AddListener((UnityAction)delegate
			{
				SaveDebugSize(debugSizeInput.text);
			});
			((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate
			{
				SaveDebugSize("1");
			});
			debugSizeHint = CreateText(parent, "0.1~10 倍;模型、碰撞体和镜头同步缩放。本局换层、复活后保留。", 15f, (FontStyles)0, (TextAlignmentOptions)514, 28f, tokenized: false);
			RefreshDebugSize();
		}

		private void StepDebugSize(int direction)
		{
			float num = DebugCharacterModule.Size(GetLocalNetworkUser());
			SaveDebugSize(Mathf.Clamp(Mathf.Round((num + (float)direction * 0.1f) * 100f) / 100f, 0.1f, 10f).ToString(CultureInfo.InvariantCulture));
		}

		private void SaveDebugSize(string text)
		{
			if (!Object.op_Implicit((Object)(object)Run.instance) && Object.op_Implicit((Object)(object)GetLocalNetworkUser()))
			{
				if (!DebugBodyScaleRules.TryParse(text, out var value))
				{
					((TMP_Text)debugSizeHint).text = "请输入 0.1~10 的大小系数,例如 0.5、1、2。";
					return;
				}
				DebugCharacterModule.Request(null, value);
				debugSizeInput.SetTextWithoutNotify(value.ToString("0.###", CultureInfo.InvariantCulture));
				((TMP_Text)debugSizeHint).text = "已发送;生命、伤害和移速不变,大小系数在开局后固定。";
			}
		}

		private void RefreshDebugSize()
		{
			if (Object.op_Implicit((Object)(object)debugSizeInput))
			{
				bool interactable = !Object.op_Implicit((Object)(object)Run.instance) && Object.op_Implicit((Object)(object)GetLocalNetworkUser());
				((Selectable)debugSizeInput).interactable = interactable;
				MPButton[] componentsInChildren = ((Component)debugSizeRow).GetComponentsInChildren<MPButton>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Selectable)componentsInChildren[i]).interactable = interactable;
				}
				float num = DebugCharacterModule.Size(GetLocalNetworkUser());
				if (!debugSizeInput.isFocused && displayedDebugSize != num)
				{
					debugSizeInput.SetTextWithoutNotify(num.ToString("0.###", CultureInfo.InvariantCulture));
					displayedDebugSize = num;
				}
			}
		}

		private void CreateExtraTabs(Transform row)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			duelTabButton = CloneButton(row, "对决", tokenized: false, -1f, 46f);
			debugTabButton = CloneButton(row, "调试角色", tokenized: false, -1f, 46f);
			((UnityEvent)((Button)duelTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(5);
			});
			((UnityEvent)((Button)debugTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(6);
			});
			commandTabButton = CloneButton(row, "统率细节", tokenized: false, -1f, 46f);
			((UnityEvent)((Button)commandTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(7);
			});
			chimeraTabButton = CloneButton(row, "奇美拉", tokenized: false, -1f, 46f);
			((UnityEvent)((Button)chimeraTabButton).onClick).AddListener((UnityAction)delegate
			{
				ShowPage(8);
			});
		}

		private void CreateExtraPages(Transform parent)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			duelPageObject = CreatePage(parent, "DuelSettings", 470f);
			((UnityEvent)((Button)CloneButton(duelPageObject.transform, "切换:基本 / 数值与时间", tokenized: false, -1f, 38f)).onClick).AddListener((UnityAction)delegate
			{
				advanced = !advanced;
				duelBasic.SetActive(!advanced);
				duelAdvanced.SetActive(advanced);
			});
			duelBasic = CreatePage(duelPageObject.transform, "Basic", 410f);
			duelAdvanced = CreatePage(duelPageObject.transform, "Advanced", 410f);
			duelAdvanced.SetActive(false);
			Transform transform = duelBasic.transform;
			Transform transform2 = duelAdvanced.transform;
			AddChoiceRow(transform, "Boss 玩家", BossPlayerLabel, delegate
			{
				CycleBossPlayer(-1);
			}, delegate
			{
				CycleBossPlayer(1);
			});
			AddChoiceRow(transform, "Boss 类型", () => DuelModule.BodyName(CurrentDuel.BossBody), delegate
			{
				Cycle(DuelConfig.BossBody, DuelModule.BossNames.Where(DuelModule.ValidBody).ToArray(), -1);
			}, delegate
			{
				Cycle(DuelConfig.BossBody, DuelModule.BossNames.Where(DuelModule.ValidBody).ToArray(), 1);
			});
			AddChoiceRow(transform, "竞技场", () => Language.GetString(DuelModule.Scene(CurrentDuel.Map).nameToken), delegate
			{
				Cycle(DuelConfig.Map, DuelModule.MapNames, -1);
			}, delegate
			{
				Cycle(DuelConfig.Map, DuelModule.MapNames, 1);
			});
			DuelNumber(transform, "挑战者等级", DuelConfig.ChallengerLevel, () => CurrentDuel.ChallengerLevel, 1, 999);
			DuelNumber(transform, "Boss 等级", DuelConfig.BossLevel, () => CurrentDuel.BossLevel, 1, 999);
			DuelNumber(transform, "挑战者每人配装点数", DuelConfig.ChallengerPoints, () => CurrentDuel.ChallengerPoints, 0, 999);
			DuelNumber(transform, "Boss 配装点数", DuelConfig.BossPoints, () => CurrentDuel.BossPoints, 0, 999);
			CreateText(transform, "沿用万神殿物品价格;每人另有 1 个免费主动装备名额。按住 Shift 每次增减 10。", 16f, (FontStyles)0, (TextAlignmentOptions)514, 34f, tokenized: false);
			DuelFloat(transform2, "挑战者生命倍率", DuelConfig.ChallengerHealth, () => CurrentDuel.ChallengerHealth);
			DuelFloat(transform2, "挑战者伤害倍率", DuelConfig.ChallengerDamage, () => CurrentDuel.ChallengerDamage);
			DuelFloat(transform2, "Boss 生命倍率", DuelConfig.BossHealth, () => CurrentDuel.BossHealth);
			DuelFloat(transform2, "Boss 伤害倍率", DuelConfig.BossDamage, () => CurrentDuel.BossDamage);
			DuelNumber(transform2, "开战倒计时(秒)", DuelConfig.Countdown, () => CurrentDuel.Countdown, 3, 30);
			DuelNumber(transform2, "战斗时限(分钟,0 为不限)", DuelConfig.TimeLimitMinutes, () => CurrentDuel.TimeLimitMinutes, 0, 120);
			DuelNumber(transform2, "开战距离(米)", DuelConfig.SpawnDistance, () => CurrentDuel.SpawnDistance, 10, 150);
			CreateText(transform2, "Boss 死亡:挑战者获胜;挑战者全灭:Boss 获胜;同时死亡或超时:平局。", 16f, (FontStyles)0, (TextAlignmentOptions)514, 34f, tokenized: false);
			BuildDebugPage(parent);
			CreateCommandPage(parent);
			CreateChimeraPage(parent);
		}

		private static void Cycle(ConfigEntry<string> entry, string[] options, int direction)
		{
			if (CanEditDuel && options.Length != 0)
			{
				entry.Value = options[(Array.IndexOf(options, entry.Value) + direction + options.Length) % options.Length];
				DuelNetwork.Broadcast();
			}
		}

		private static string BossPlayerLabel()
		{
			string id = CurrentDuel.BossPlayer;
			NetworkUser val = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)((NetworkUser candidate) => Object.op_Implicit((Object)(object)candidate) && ((object)candidate.id/*cast due to .constrained prefix*/).ToString() == id));
			if (!Object.op_Implicit((Object)(object)val))
			{
				return "房主 / 首位玩家";
			}
			return EscapeRichText(val.userName);
		}

		private static void CycleBossPlayer(int direction)
		{
			Cycle(DuelConfig.BossPlayer, new string[1] { "" }.Concat<string>(from user in DuelRunController.ConnectedUsers()
				select ((object)user.id/*cast due to .constrained prefix*/).ToString()).ToArray(), direction);
		}

		private void DuelNumber(Transform parent, string label, ConfigEntry<int> entry, Func<int> value, int min, int max)
		{
			AddChoiceRow(parent, label, () => value().ToString(), delegate
			{
				ChangeDuelNumber(entry, min, max, -1);
			}, delegate
			{
				ChangeDuelNumber(entry, min, max, 1);
			});
		}

		private void ChangeDuelNumber(ConfigEntry<int> entry, int min, int max, int direction)
		{
			if (CanEditDuel)
			{
				entry.Value = Math.Clamp(entry.Value + direction * ((!Input.GetKey((KeyCode)304)) ? 1 : 10), min, max);
				DuelNetwork.Broadcast();
			}
		}

		private void DuelFloat(Transform parent, string label, ConfigEntry<float> entry, Func<float> value)
		{
			AddChoiceRow(parent, label, () => $"× {value():0.0}", delegate
			{
				Change(-1);
			}, delegate
			{
				Change(1);
			});
			void Change(int direction)
			{
				if (CanEditDuel)
				{
					entry.Value = Mathf.Clamp(Mathf.Round((entry.Value + (float)direction * 0.1f) * 10f) / 10f, 0.1f, 100f);
					DuelNetwork.Broadcast();
				}
			}
		}

		private void BuildDebugPage(Transform parent)
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Expected O, but got Unknown
			//IL_0086: 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_0091: Expected O, but got Unknown
			debugPageObject = CreatePage(parent, "DebugCharacters", 470f);
			debugSelection = CreateText(debugPageObject.transform, "", 20f, (FontStyles)1, (TextAlignmentOptions)514, 35f, tokenized: false);
			Transform val = CreateRow(debugPageObject.transform);
			ButtonClickedEvent onClick = ((Button)CloneButton(val, "使用所选幸存者", tokenized: false, 220f, 38f)).onClick;
			object obj = <>c.<>9__61_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					DebugCharacterModule.Request("");
				};
				<>c.<>9__61_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			GameObject val3 = new GameObject("Search", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField),
				typeof(LayoutElement)
			});
			val3.layer = ((Component)parent).gameObject.layer;
			val3.transform.SetParent(val, false);
			val3.GetComponent<LayoutElement>().flexibleWidth = 1f;
			((Graphic)val3.GetComponent<Image>()).color = new Color(0.08f, 0.12f, 0.16f);
			HGTextMeshProUGUI val4 = CreateText(val3.transform, "", 18f, (FontStyles)0, (TextAlignmentOptions)4097, 38f, tokenized: false);
			Stretch((RectTransform)((TMP_Text)val4).transform);
			TMP_InputField component = val3.GetComponent<TMP_InputField>();
			component.textViewport = (RectTransform)val3.transform;
			component.textComponent = (TMP_Text)(object)val4;
			HGTextMeshProUGUI val5 = CreateText(val3.transform, "搜索名称 / Body 名称", 18f, (FontStyles)2, (TextAlignmentOptions)4097, 38f, tokenized: false);
			Stretch((RectTransform)((TMP_Text)val5).transform);
			((Graphic)val5).color = Color.gray;
			component.placeholder = (Graphic)(object)val5;
			((UnityEvent<string>)(object)component.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
			{
				debugSearch = value;
				debugPage = 0;
				RebuildDebugGrid();
			});
			CreateDebugSizeControls(debugPageObject.transform);
			debugGrid = CreatePage(debugPageObject.transform, "BodyGrid", 230f).transform;
			Transform parent2 = CreateRow(debugPageObject.transform);
			MPButton val6 = CloneButton(parent2, "上一页", tokenized: false, 150f, 38f);
			debugPageLabel = CreateText(parent2, "", 18f, (FontStyles)0, (TextAlignmentOptions)514, 38f, tokenized: false);
			((Component)debugPageLabel).GetComponent<LayoutElement>().flexibleWidth = 1f;
			MPButton obj2 = CloneButton(parent2, "下一页", tokenized: false, 150f, 38f);
			((UnityEvent)((Button)val6).onClick).AddListener((UnityAction)delegate
			{
				debugPage--;
				RebuildDebugGrid();
			});
			((UnityEvent)((Button)obj2).onClick).AddListener((UnityAction)delegate
			{
				debugPage++;
				RebuildDebugGrid();
			});
			RebuildDebugGrid();
		}

		private void RebuildDebugGrid()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			foreach (Transform item in debugGrid)
			{
				((Component)item).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			string[] array = DebugCharacterModule.Candidates.Where((string name) => name.IndexOf(debugSearch, StringComparison.OrdinalIgnoreCase) >= 0 || DuelModule.BodyName(name).IndexOf(debugSearch, StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
			int num = Math.Max(1, (array.Length + 8 - 1) / 8);
			debugPage = (debugPage % num + num) % num;
			((TMP_Text)debugPageLabel).text = $"{debugPage + 1} / {num} · {array.Length} 个角色";
			Transform parent = debugGrid;
			for (int num2 = debugPage * 8; num2 < Math.Min(array.Length, (debugPage + 1) * 8); num2++)
			{
				if (num2 % 2 == 0)
				{
					parent = CreateRow(debugGrid);
				}
				string selected = array[num2];
				((UnityEvent)((Button)CloneButton(parent, DuelModule.BodyName(selected) + "\n<size=12>" + selected + "</size>", tokenized: false, -1f, 48f)).onClick).AddListener((UnityAction)delegate
				{
					DebugCharacterModule.Request(selected);
				});
			}
		}

		private void RefreshDebugSelection()
		{
			if (Object.op_Implicit((Object)(object)debugSelection))
			{
				string text = DebugCharacterModule.Choice(GetLocalNetworkUser());
				((TMP_Text)debugSelection).text = ((text.Length == 0) ? "本局角色:使用所选幸存者" : ("本局角色:" + DuelModule.BodyName(text) + "(" + text + ")"));
				HGTextMeshProUGUI obj = debugSelection;
				((TMP_Text)obj).text = ((TMP_Text)obj).text + $" · 体型 ×{DebugCharacterModule.Size(GetLocalNetworkUser()):0.###}";
				RefreshDebugSize();
			}
		}

		private void UpdateExtraPages()
		{
			if (Time.unscaledTime < nextExtraRefresh)
			{
				return;
			}
			nextExtraRefresh = Time.unscaledTime + 0.5f;
			bool isSelected = DuelModule.IsSelected;
			if (NetworkServer.active && isSelected)
			{
				DuelNetwork.Broadcast();
			}
			if (!Object.op_Implicit((Object)(object)duelTabButton))
			{
				return;
			}
			((Component)duelTabButton).gameObject.SetActive(isSelected);
			if (!isSelected && currentPage == 5)
			{
				ShowPage(0);
			}
			if (!Object.op_Implicit((Object)(object)overlayObject) || !overlayObject.activeSelf)
			{
				return;
			}
			if (currentPage == 7)
			{
				RefreshCommandPage();
			}
			if (currentPage == 8)
			{
				RefreshChimera();
			}
			if (currentPage == 5)
			{
				MPButton[] componentsInChildren = duelBasic.GetComponentsInChildren<MPButton>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Selectable)componentsInChildren[i]).interactable = CanEditDuel;
				}
				componentsInChildren = duelAdvanced.GetComponentsInChildren<MPButton>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Selectable)componentsInChildren[i]).interactable = CanEditDuel;
				}
				RefreshValues();
			}
			if (currentPage == 6)
			{
				DebugCharacterModule.Request();
				RefreshDebugSelection();
			}
		}

		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();
				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()
		{
			UpdateExtraPages();
			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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			GameObject val = (Object.op_Implicit((Object)(object)settingsStyleTemplate) ? ((Component)settingsStyleTemplate).gameObject : ((Component)buttonTemplate).gameObject);
			openButtonObject = Object.Instantiate<GameObject>(val, ((Component)buttonTemplate).transform.parent, false);
			((Object)openButtonObject).name = "ResonatorsOfTheSoulSettingsButton";
			RectTransform val2 = (RectTransform)openButtonObject.transform;
			RectTransform val3 = (RectTransform)((Component)buttonTemplate).transform;
			val2.anchorMin = val3.anchorMin;
			val2.anchorMax = val3.anchorMax;
			val2.pivot = val3.pivot;
			val2.sizeDelta = val3.sizeDelta;
			Vector2 anchoredPosition = val3.anchoredPosition;
			Rect rect = val3.rect;
			val2.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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Expected O, but got Unknown
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Expected O, but got Unknown
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: 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.SetActive(false);
			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.035f, 0.055f, 0.065f, 0.78f);
			((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.56f, 0.65f, 0.69f, 0.78f);
			((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 = 0f;
			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);
			CreateExtraPages(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.56f, 0.7f, 0.76f, 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: 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;
			val.GetComponent<LayoutElement>().minHeight = 48f;
			val.GetComponent<LayoutElement>().flexibleHeight = 0f;
			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);
			});
			CreateExtraTabs(val.transform);
			MPButton[] componentsInChildren = val.GetComponentsInChildren<MPButton>(true);
			foreach (MPButton obj in componentsInChildren)
			{
				LayoutElement component2 = ((Component)obj).GetComponent<LayoutElement>();
				component2.minWidth = 0f;
				component2.preferredWidth = 0f;
				component2.flexibleWidth = 1f;
				TMP_Text componentInChildren = ((Component)obj).GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.fontStyle = (FontStyles)0;
					componentInChildren.enableAutoSizing = false;
					componentInChildren.fontSize = 16f;
				}
			}
		}

		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.16f, 0.22f, 0.26f, 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(0.76f, 0.92f, 1f, 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 mi