Decompiled source of RiskOfArena v1.0.12

plugins/ArenaPvP/ArenaPvP.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
using RoR2.Navigation;
using RoR2.Projectile;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyInformationalVersion("1.0.12")]
[assembly: AssemblyCompany("claytemplar")]
[assembly: AssemblyVersion("1.0.12.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ArenaPvP
{
	internal static class ArenaArtwork
	{
		private static readonly Dictionary<int, AsyncOperationHandle<Texture>> maps = new Dictionary<int, AsyncOperationHandle<Texture>>();

		private static readonly Dictionary<int, Sprite> mapSprites = new Dictionary<int, Sprite>();

		private static readonly Dictionary<int, AsyncOperationHandle<Sprite>> pickups = new Dictionary<int, AsyncOperationHandle<Sprite>>();

		internal static Sprite Map(int index)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			if (mapSprites.TryGetValue(index, out var value))
			{
				return value;
			}
			SceneDef sceneDef = SceneCatalog.GetSceneDef((SceneIndex)index);
			if (!Object.op_Implicit((Object)(object)sceneDef))
			{
				return null;
			}
			Texture2D val = null;
			AssetReferenceTexture previewTextureReference = sceneDef.previewTextureReference;
			if (previewTextureReference != null && ((AssetReference)previewTextureReference).RuntimeKeyIsValid())
			{
				if (!maps.TryGetValue(index, out var value2))
				{
					value2 = Addressables.LoadAssetAsync<Texture>(((AssetReference)previewTextureReference).RuntimeKey);
					maps.Add(index, value2);
				}
				if (value2.IsDone && (int)value2.Status == 1)
				{
					Texture result = value2.Result;
					val = (Texture2D)(object)((result is Texture2D) ? result : null);
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				Texture previewTexture = sceneDef.previewTexture;
				val = (Texture2D)(object)((previewTexture is Texture2D) ? previewTexture : null);
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			mapSprites.Add(index, value);
			return value;
		}

		internal static Sprite Pickup(int index)
		{
			//IL_0001: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			PickupDef pickupDef = PickupCatalog.GetPickupDef(new PickupIndex(index));
			if (pickupDef == null)
			{
				return null;
			}
			if (Object.op_Implicit((Object)(object)pickupDef.iconSprite))
			{
				return pickupDef.iconSprite;
			}
			AssetReferenceT<Sprite> iconSpriteReference = pickupDef.iconSpriteReference;
			if (iconSpriteReference == null || !((AssetReference)iconSpriteReference).RuntimeKeyIsValid())
			{
				return null;
			}
			if (!pickups.TryGetValue(index, out var value))
			{
				value = Addressables.LoadAssetAsync<Sprite>(((AssetReference)iconSpriteReference).RuntimeKey);
				pickups.Add(index, value);
			}
			if (!value.IsDone || (int)value.Status != 1)
			{
				return null;
			}
			return value.Result;
		}

		internal static void Dispose()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			foreach (Sprite value in mapSprites.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)value);
				}
			}
			foreach (AsyncOperationHandle<Texture> value2 in maps.Values)
			{
				if (value2.IsValid())
				{
					Addressables.Release<Texture>(value2);
				}
			}
			foreach (AsyncOperationHandle<Sprite> value3 in pickups.Values)
			{
				if (value3.IsValid())
				{
					Addressables.Release<Sprite>(value3);
				}
			}
			maps.Clear();
			mapSprites.Clear();
			pickups.Clear();
		}
	}
	internal sealed class ArenaOptionArt : MonoBehaviour
	{
		internal Image Image;

		private int pickup = -1;

		internal void Bind(int index)
		{
			pickup = index;
			Refresh();
		}

		internal void Set(Sprite sprite)
		{
			pickup = -1;
			Image.sprite = sprite;
			((Behaviour)Image).enabled = Object.op_Implicit((Object)(object)sprite);
		}

		private void LateUpdate()
		{
			Refresh();
		}

		private void Refresh()
		{
			if (pickup >= 0 && Object.op_Implicit((Object)(object)Image))
			{
				Sprite val = ArenaArtwork.Pickup(pickup);
				if (Object.op_Implicit((Object)(object)val))
				{
					Image.sprite = val;
					((Behaviour)Image).enabled = true;
				}
			}
		}
	}
	internal sealed class ArenaCommandPanel : MonoBehaviour
	{
		internal GridLayoutGroup gridlayoutGroup;

		internal RectTransform buttonContainer;

		internal GameObject buttonPrefab;

		internal Image[] coloredImages;

		internal Image[] darkColoredImages;

		internal int maxColumnCount;

		internal static ArenaCommandPanel Create(GameObject root, PickupPickerPanel template)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)template) || !Object.op_Implicit((Object)(object)template.buttonContainer) || !Object.op_Implicit((Object)(object)template.buttonPrefab) || !Object.op_Implicit((Object)(object)template.gridlayoutGroup))
			{
				throw new InvalidOperationException("The Command panel visual template is incomplete.");
			}
			ArenaCommandPanel arenaCommandPanel = root.AddComponent<ArenaCommandPanel>();
			GameObject val = new GameObject("Arena Options", new Type[2]
			{
				typeof(RectTransform),
				typeof(GridLayoutGroup)
			});
			val.transform.SetParent(root.transform, false);
			arenaCommandPanel.gridlayoutGroup = val.GetComponent<GridLayoutGroup>();
			((LayoutGroup)arenaCommandPanel.gridlayoutGroup).childAlignment = (TextAnchor)1;
			arenaCommandPanel.buttonContainer = val.GetComponent<RectTransform>();
			arenaCommandPanel.buttonPrefab = template.buttonPrefab;
			arenaCommandPanel.coloredImages = (Image[])(object)new Image[0];
			arenaCommandPanel.darkColoredImages = (Image[])(object)new Image[0];
			return arenaCommandPanel;
		}

		internal MPButton[] Populate(Option[] options)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			foreach (Transform item in (Transform)buttonContainer)
			{
				((Component)item).gameObject.SetActive(false);
			}
			MPButton[] array = (MPButton[])(object)new MPButton[options.Length];
			for (int i = 0; i < options.Length; i++)
			{
				GameObject val = new GameObject("Arena Option " + i, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent((Transform)(object)buttonContainer, false);
				GameObject val2 = Object.Instantiate<GameObject>(buttonPrefab, val.transform, false);
				RectTransform component = val2.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				Vector2 offsetMin = (component.offsetMax = Vector2.zero);
				component.offsetMin = offsetMin;
				((Transform)component).localScale = Vector3.one;
				val2.SetActive(true);
				MPButton component2 = val2.GetComponent<MPButton>();
				if (!Object.op_Implicit((Object)(object)component2))
				{
					throw new InvalidOperationException("The Command button template has no MPButton.");
				}
				((Button)component2).onClick = new ButtonClickedEvent();
				((Selectable)component2).interactable = options[i].available;
				TooltipProvider[] componentsInChildren = val2.GetComponentsInChildren<TooltipProvider>(true);
				foreach (TooltipProvider obj in componentsInChildren)
				{
					obj.AllowTooltipOnNavigationSelect = false;
					((Behaviour)obj).enabled = false;
				}
				ChildLocator component3 = val2.GetComponent<ChildLocator>();
				Transform val3 = (Object.op_Implicit((Object)(object)component3) ? component3.FindChild("Icon") : null);
				if (Object.op_Implicit((Object)(object)val3))
				{
					((Component)val3).gameObject.SetActive(false);
				}
				GameObject val4 = new GameObject("Persistent artwork", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val4.transform.SetParent(val.transform, false);
				ArenaStyle.Fill(val4.GetComponent<RectTransform>(), 4f, 4f, 4f, 4f);
				Image component4 = val4.GetComponent<Image>();
				component4.preserveAspect = true;
				((Graphic)component4).raycastTarget = false;
				((Graphic)component4).color = (options[i].available ? Color.white : Color.gray);
				ArenaOptionArt arenaOptionArt = val.AddComponent<ArenaOptionArt>();
				arenaOptionArt.Image = component4;
				arenaOptionArt.Bind(options[i].pickup.pickupIndex.value);
				array[i] = component2;
			}
			for (int k = 0; k < array.Length; k++)
			{
				Navigation navigation = ((Selectable)array[k]).navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnLeft = (Selectable)(object)((k % maxColumnCount > 0) ? array[k - 1] : null);
				((Navigation)(ref navigation)).selectOnRight = (Selectable)(object)((k % maxColumnCount < maxColumnCount - 1 && k + 1 < array.Length) ? array[k + 1] : null);
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)((k >= maxColumnCount) ? array[k - maxColumnCount] : null);
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)((k + maxColumnCount < array.Length) ? array[k + maxColumnCount] : null);
				((Selectable)array[k]).navigation = navigation;
			}
			return array;
		}
	}
	internal sealed class ArenaConfig
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__59_1;

			public static UnityAction <>9__59_2;

			public static IntSliderTryParse <>9__65_1;

			internal void <.ctor>b__59_1()
			{
				ArenaStageSettings.Open(editBlacklist: true);
			}

			internal void <.ctor>b__59_2()
			{
				ArenaStageSettings.Open(editBlacklist: false);
			}

			internal bool <EssencePercentage>b__65_1(string input, CultureInfo culture, out int parsed)
			{
				return int.TryParse((input ?? "").Trim().TrimEnd('%').Trim(), NumberStyles.Integer, culture, out parsed);
			}
		}

		internal readonly ConfigEntry<ItemSelection> Selection;

		internal readonly ConfigEntry<RespawnRule> Respawn;

		internal readonly ConfigEntry<bool> OnStart;

		internal readonly ConfigEntry<bool> OnDeath;

		internal readonly ConfigEntry<bool> OnKill;

		internal readonly ConfigEntry<bool> OnTimer;

		internal readonly ConfigEntry<bool> AllowLevel;

		internal readonly ConfigEntry<bool> IncludeLunar;

		internal readonly ConfigEntry<bool> IncludeVoid;

		internal readonly ConfigEntry<bool> IncludeBoss;

		internal readonly ConfigEntry<bool> IncludeSpecial;

		internal readonly ConfigEntry<bool> IncludeEquipment;

		internal readonly ConfigEntry<bool> IncludeRestricted;

		internal readonly ConfigEntry<bool> Catchup;

		internal readonly ConfigEntry<bool> NoFallDamage;

		internal readonly ConfigEntry<bool> AutoOpen;

		internal readonly ConfigEntry<bool> ShowNametags;

		internal readonly ConfigEntry<bool> ShowOpponentArrows;

		internal readonly ConfigEntry<bool> EnableScrapper;

		internal readonly ConfigEntry<int> StartingRewards;

		internal readonly ConfigEntry<int> DeathRewards;

		internal readonly ConfigEntry<int> KillRewards;

		internal readonly ConfigEntry<int> TimedRewards;

		internal readonly ConfigEntry<int> DraftSize;

		internal readonly ConfigEntry<int> KillLimit;

		internal readonly ConfigEntry<int> InitialCap;

		internal readonly ConfigEntry<int> CapStep;

		internal readonly ConfigEntry<int> MaximumLevel;

		internal readonly ConfigEntry<int> CommonWeight;

		internal readonly ConfigEntry<int> GreenWeight;

		internal readonly ConfigEntry<int> RedWeight;

		internal readonly ConfigEntry<int> WhiteEssenceChance;

		internal readonly ConfigEntry<int> GreenEssenceChance;

		internal readonly ConfigEntry<int> RedEssenceChance;

		internal readonly ConfigEntry<int> VoidEssenceChance;

		internal readonly ConfigEntry<int> LunarEssenceChance;

		internal readonly ConfigEntry<float> ItemInterval;

		internal readonly ConfigEntry<float> RespawnSeconds;

		internal readonly ConfigEntry<float> ProtectionSeconds;

		internal readonly ConfigEntry<float> CapInterval;

		internal readonly ConfigEntry<float> MatchMinutes;

		internal readonly ConfigEntry<float> WarmupSeconds;

		internal readonly ConfigEntry<float> DamageScale;

		internal readonly ConfigEntry<float> HealOnKill;

		internal readonly ConfigEntry<string> BannedItems;

		internal readonly ConfigEntry<string> BannedEquipment;

		internal readonly ConfigEntry<string> MapBlacklist;

		internal readonly ConfigEntry<string> DefaultMap;

		internal readonly ConfigEntry<KeyboardShortcut> PickerKey;

		internal readonly ConfigEntry<KeyboardShortcut> BoardKey;

		internal readonly ConfigEntry<KeyboardShortcut> VoteKey;

		private readonly ConfigFile file;

		private readonly List<ConfigEntryBase> matchEntries = new List<ConfigEntryBase>();

		internal IEnumerable<ConfigEntryBase> MatchEntries => matchEntries;

		internal uint MatchRevision { get; private set; } = 1u;

		internal ArenaConfig(ConfigFile file)
		{
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Expected O, but got Unknown
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Expected O, but got Unknown
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fa: Expected O, but got Unknown
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			//IL_070b: Expected O, but got Unknown
			//IL_0712: Unknown result type (might be due to invalid IL or missing references)
			//IL_071c: Expected O, but got Unknown
			//IL_077c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Expected O, but got Unknown
			//IL_0771: Unknown result type (might be due to invalid IL or missing references)
			//IL_0776: Unknown result type (might be due to invalid IL or missing references)
			//IL_077c: Expected O, but got Unknown
			//IL_07e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f0: Expected O, but got Unknown
			//IL_07db: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e6: Expected O, but got Unknown
			this.file = file;
			file.SettingChanged += delegate(object sender, SettingChangedEventArgs args)
			{
				if (matchEntries.Contains(args.ChangedSetting))
				{
					MatchRevision++;
					if (MatchRevision == 0)
					{
						MatchRevision = 1u;
					}
				}
			};
			Selection = Choice("01 Rewards", "Item selection", ItemSelection.Command, "Random grants automatically. Command offers every essence and its items. Draft offers a fixed shortlist per essence. WeightedEssence rolls one essence per reward using the five percentage controls directly below, then lets you choose its item or XP. Defaults: White 60%, Green 25%, Red 10%, Void 3%, Lunar 2%. Host rules apply next run.");
			WhiteEssenceChance = EssencePercentage("White essence chance", 60);
			GreenEssenceChance = EssencePercentage("Green essence chance", 25);
			RedEssenceChance = EssencePercentage("Red essence chance", 10);
			VoidEssenceChance = EssencePercentage("Void essence chance", 3);
			LunarEssenceChance = EssencePercentage("Lunar essence chance", 2);
			int value = file.Bind<int>("01 Rewards", "Rewards per event", 1, "Legacy shared amount. The separate death, kill and timed reward amounts replace this setting.").Value;
			value = Math.Max(0, Math.Min(12, value));
			OnStart = Check("01 Rewards", "Give starting rewards", value: true, "Give the configured number of rewards once at the beginning of a new match.");
			StartingRewards = Integer("01 Rewards", "Starting rewards", 3, 0, 12, "Exact number of starting rewards when the toggle above is enabled.");
			OnDeath = Check("01 Rewards", "Reward on death", value: true, "Give the defeated player the number of rewards below. Void/out-of-bounds deaths never award extra rewards.");
			DeathRewards = Integer("01 Rewards", "Rewards per death", value, 0, 12, "Exact ordinary death reward amount. Zero or disabling the death toggle uses timed respawning without a forced reward. An explicitly enabled underdog bonus can add one more. Void/out-of-bounds deaths give none.");
			Catchup = Check("01 Rewards", "Extra reward for underdog deaths", value: false, "Opt-in extra death reward when at least three kills behind. Adds ONE to Rewards per death; disabled by default to avoid unexpected double rewards. Never applies to void/out-of-bounds deaths.");
			OnKill = Check("01 Rewards", "Reward on kill", value: false, "Reward a player for a PvP kill. Suicides never grant kill rewards.");
			KillRewards = Integer("01 Rewards", "Rewards per kill", value, 0, 12, "Number of rewards for a PvP kill when the toggle above is enabled. Void/out-of-bounds deaths do not generate item rewards for either player.");
			OnTimer = Check("01 Rewards", "Timed rewards", value: true, "Give every connected player rewards at a shared interval, including while dead.");
			TimedRewards = Integer("01 Rewards", "Rewards per timer", value, 0, 12, "Number of rewards at each timed interval when the toggle above is enabled. A maximum of 12 rewards can be banked.");
			ItemInterval = Number("01 Rewards", "Seconds between rewards", 30f, 5f, 600f, "Match time between timed rewards.");
			DraftSize = Integer("01 Rewards", "Draft choices", 4, 2, 10, "Different pickups per essence in Draft mode. Opening an essence does not reroll its shortlist. XP is a separate choice.");
			IncludeLunar = Check("02 Item pool", "Include lunar", value: true, "Allow lunar items, except items on the ban list.");
			IncludeVoid = Check("02 Item pool", "Include void", value: true, "Allow void items from enabled expansions. Native corruption rules apply.");
			IncludeBoss = Check("02 Item pool", "Include boss", value: true, "Allow boss items.");
			IncludeSpecial = Check("02 Item pool", "Include expansion special tiers", value: true, "Include special item tiers from enabled DLCs or item mods. Hidden/internal items remain excluded.");
			IncludeRestricted = Check("02 Item pool", "Include restricted pickups", value: true, "Include visible tiered items that ordinary drops, unlocks or world-unique rules would exclude. Enabled DLC, category settings and host bans still apply. Disable to use normal run drop restrictions.");
			IncludeEquipment = Check("02 Item pool", "Include equipment essence", value: true, "Offer the equipment command essence. Choosing equipment replaces the current active equipment slot without dropping a duplicate.");
			CommonWeight = Integer("02 Item pool", "Common tier weight", 70, 0, 100, "Relative weight of the common pool for automatic Random rewards. Essence choices are unrestricted by tier weights.");
			GreenWeight = Integer("02 Item pool", "Uncommon tier weight", 25, 0, 100, "Relative weight of the uncommon pool.");
			RedWeight = Integer("02 Item pool", "Legendary tier weight", 5, 0, 100, "Relative weight of the legendary pool. Other enabled tiers each use weight 5.");
			BannedItems = file.Bind<string>("02 Item pool", "Banned internal item names", "ExtraLife,ExtraLifeVoid,ExtraLifeShrine,UseAmbientLevel,LevelBonus,InvadingDoppelganger,Doppelganger,ArtifactKey", "Comma separated internal ItemDef names, not translated display names. LevelBonus and UseAmbientLevel are always reserved for the level system.");
			Add((BaseOption)new StringInputFieldOption(BannedItems));
			Track((ConfigEntryBase)(object)BannedItems);
			if (BannedItems.Value == "ExtraLife,ExtraLifeVoid,ExtraLifeShrine,UseAmbientLevel,LevelBonus,InvadingDoppelganger,Doppelganger,ArtifactKey,ScrapWhite,ScrapGreen,ScrapRed,ScrapYellow,ScrapLunar")
			{
				BannedItems.Value = "ExtraLife,ExtraLifeVoid,ExtraLifeShrine,UseAmbientLevel,LevelBonus,InvadingDoppelganger,Doppelganger,ArtifactKey,ScrapWhite,ScrapGreen,ScrapRed,ScrapYellow,ScrapLunar".Substring(0, "ExtraLife,ExtraLifeVoid,ExtraLifeShrine,UseAmbientLevel,LevelBonus,InvadingDoppelganger,Doppelganger,ArtifactKey,ScrapWhite,ScrapGreen,ScrapRed,ScrapYellow,ScrapLunar".IndexOf(",ScrapWhite", StringComparison.Ordinal));
			}
			BannedEquipment = file.Bind<string>("02 Item pool", "Banned internal equipment names", "QuestVolatileBattery", "Comma separated EquipmentDef names excluded from rewards.");
			Add((BaseOption)new StringInputFieldOption(BannedEquipment));
			Track((ConfigEntryBase)(object)BannedEquipment);
			AllowLevel = Check("03 Levels", "Offer XP instead of item", value: true, "In Command, Draft or WeightedEssence, spend one reward to gain exactly one personal survivor level. Team XP is disabled.");
			InitialCap = Integer("03 Levels", "Starting level cap", 3, 1, 99, "Highest personal level allowed when the match starts. Players still start at level 1.");
			CapInterval = Number("03 Levels", "Seconds between cap increases", 60f, 5f, 3600f, "Active match time between level cap increases. Warmup and item menus do not accelerate the clock.");
			CapStep = Integer("03 Levels", "Levels added to cap", 1, 1, 20, "How many extra levels become available per interval.");
			MaximumLevel = Integer("03 Levels", "Absolute maximum level", 30, 1, 99, "The cap never exceeds this level.");
			Respawn = Choice("04 Respawn", "Respawn rule", RespawnRule.TimerAndChoice, "Timer: return after delay. AfterChoice: return after one death choice (minimum 1 second). TimerAndChoice: both. If death rewards are off, zero, impossible or prohibited for a void death, use the configured timer without creating a free choice. Random rewards always use the timer.");
			RespawnSeconds = Number("04 Respawn", "Respawn delay seconds", 5f, 1f, 120f, "Time from death to respawn when a timer is required.");
			ProtectionSeconds = Number("04 Respawn", "Spawn protection seconds", 3f, 0f, 15f, "Invulnerability on spawn. Hitting another player ends your protection.");
			NoFallDamage = Check("04 Respawn", "Disable fall damage", value: true, "Ignore fall damage during Arena matches. Out-of-bounds deaths still respawn.");
			KillLimit = Integer("05 Match", "Kills to win", 20, 0, 200, "Finish at this many PvP kills. Zero disables the kill limit.");
			MatchMinutes = Number("05 Match", "Match duration minutes", 10f, 0f, 120f, "Finish when active match time expires. Zero disables the time limit. Tied leaders share the win.");
			WarmupSeconds = Number("05 Match", "Warmup seconds", 10f, 0f, 120f, "Initial preparation time with damage disabled. Choose starting rewards during warmup.");
			DamageScale = Number("05 Match", "PvP damage multiplier", 0.5f, 0.05f, 3f, "Multiplier applied to damage from another player or their summon.");
			HealOnKill = Number("05 Match", "Heal fraction on kill", 0.25f, 0f, 1f, "Restore this fraction of maximum health on a PvP kill.");
			EnableScrapper = Check("05 Match", "Enable Arena scrapper", value: true, "Host-controlled Arena rule. Spawn the reward scrapper with its highlight and marker. Recycled rewards keep the exact item tier in Random, Draft and Weighted Essence; Command stays unrestricted. Disable to remove it and block recycling. Applies live to everyone in the host's match; clients cannot override it. Vanilla scrappers are unchanged.");
			bool value2 = file.Bind<bool>("05 Match", "Show player nametags", true, "Legacy preference, migrated to 06 Local controls. This value no longer controls other players' nametags.").Value;
			ShowNametags = Check("06 Local controls", "Show player nametags", value2, "Show overhead player names on your screen in Arena. Opponent arrows have a separate toggle below. This preference applies immediately on your own client; scoreboard names remain visible.");
			ShowOpponentArrows = Check("06 Local controls", "Show opponent arrows", value: true, "Show the game's small position arrows above opposing players, independently of overhead names. Applies immediately on your own screen in Arena.");
			AutoOpen = Check("06 Local controls", "Open new rewards automatically", value: false, "Open the picker for new rewards while alive. Required death choices always open. Double-tap and release W to close without spending a reward; holding W does not close it. This preference is local and live.");
			PickerKey = file.Bind<KeyboardShortcut>("06 Local controls", "Open reward picker", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), "Open or close the personal reward picker.");
			BoardKey = file.Bind<KeyboardShortcut>("06 Local controls", "Toggle scoreboard", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Toggle the scoreboard.");
			VoteKey = file.Bind<KeyboardShortcut>("06 Local controls", "Open map vote", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Open or close the Arena-only lobby map vote.");
			Add((BaseOption)new KeyBindOption(PickerKey));
			Add((BaseOption)new KeyBindOption(BoardKey));
			Add((BaseOption)new KeyBindOption(VoteKey));
			MapBlacklist = file.Bind<string>("07 Maps", "Blacklisted map names", "bazaar", "Comma separated internal scene names or translated map names. Default: bazaar (Bazaar Between Time). All playable maps from enabled expansions are eligible unless blacklisted. Applies live in the Arena lobby.");
			Track((ConfigEntryBase)(object)MapBlacklist);
			object obj = <>c.<>9__59_1;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					ArenaStageSettings.Open(editBlacklist: true);
				};
				<>c.<>9__59_1 = val;
				obj = (object)val;
			}
			Add((BaseOption)new GenericButtonOption("Blacklisted map names", "07 Maps", "Open every playable stage with its image. Tick a stage to blacklist it, untick to allow it, then Apply. Bazaar Between Time is blacklisted by default.", "Choose stages", (UnityAction)obj));
			DefaultMap = file.Bind<string>("07 Maps", "Default map", "golemplains", "Host's starting map when nobody has voted. Use the internal scene name (golemplains = Titanic Plains) or the displayed map name. Blacklist and enabled DLC rules take priority; an unavailable default falls back to the first allowed map. Applies live in the Arena lobby.");
			Track((ConfigEntryBase)(object)DefaultMap);
			object obj2 = <>c.<>9__59_2;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					ArenaStageSettings.Open(editBlacklist: false);
				};
				<>c.<>9__59_2 = val2;
				obj2 = (object)val2;
			}
			Add((BaseOption)new GenericButtonOption("Default map", "07 Maps", "Choose one stage by image as the host's default when no votes are cast, then Apply. Blacklist and enabled-DLC rules take priority.", "Choose stage", (UnityAction)obj2));
			ModSettingsManager.SetModDescription("A host-authoritative free-for-all arena, selected immediately after Monsoon. The host decides match rules, rewards, levels, respawns and map eligibility. Gameplay rules apply to new runs, except the live Arena scrapper toggle; host map settings apply live in the lobby. Hotkeys, names, opponent arrows and automatic menu opening are personal preferences on your own client.", "com.fireb.arenapvp", "RiskOfArena");
		}

		private void Add(BaseOption option)
		{
			ModSettingsManager.AddOption(option, "com.fireb.arenapvp", "RiskOfArena");
		}

		private void Track(ConfigEntryBase entry)
		{
			if (ArenaRules.IsMatchSettingGroup(entry.Definition.Section) && !matchEntries.Contains(entry))
			{
				matchEntries.Add(entry);
			}
		}

		private ConfigEntry<bool> Check(string group, string name, bool value, string description)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			ConfigEntry<bool> val = file.Bind<bool>(group, name, value, description);
			Add((BaseOption)new CheckBoxOption(val));
			Track((ConfigEntryBase)(object)val);
			return val;
		}

		private ConfigEntry<T> Choice<T>(string group, string name, T value, string description)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			ConfigEntry<T> val = file.Bind<T>(group, name, value, description);
			Add((BaseOption)new ChoiceOption((ConfigEntryBase)(object)val));
			Track((ConfigEntryBase)(object)val);
			return val;
		}

		private ConfigEntry<int> Integer(string group, string name, int value, int min, int max, string description)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			ConfigEntry<int> val = file.Bind<int>(group, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), Array.Empty<object>()));
			Add((BaseOption)new IntSliderOption(val, new IntSliderConfig
			{
				min = min,
				max = max
			}));
			Track((ConfigEntryBase)(object)val);
			return val;
		}

		private ConfigEntry<int> EssencePercentage(string name, int value)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0072: 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_007d: Expected O, but got Unknown
			ConfigEntry<int> val = file.Bind<int>("01 Rewards", name, value, new ConfigDescription("WeightedEssence only. 0 excludes this class. Set the five values to a total of 100 for exact percentages; other totals are automatically normalized among enabled classes with available items. All zero offers only XP when allowed; otherwise that reward is skipped without blocking respawn. Host values are captured for the next new run.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			IntSliderConfig val2 = new IntSliderConfig
			{
				min = 0,
				max = 100,
				formatString = "{0}%",
				checkIfDisabled = (IsDisabledDelegate)(() => Selection.Value != ItemSelection.WeightedEssence)
			};
			object obj = <>c.<>9__65_1;
			if (obj == null)
			{
				IntSliderTryParse val3 = delegate(string input, CultureInfo culture, out int parsed)
				{
					return int.TryParse((input ?? "").Trim().TrimEnd('%').Trim(), NumberStyles.Integer, culture, out parsed);
				};
				<>c.<>9__65_1 = val3;
				obj = (object)val3;
			}
			val2.TryParseDelegate = (IntSliderTryParse)obj;
			Add((BaseOption)new IntSliderOption(val, val2));
			Track((ConfigEntryBase)(object)val);
			return val;
		}

		private ConfigEntry<float> Number(string group, string name, float value, float min, float max, string description)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_006b: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			ConfigEntry<float> val = file.Bind<float>(group, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
			Add((BaseOption)new StepSliderOption(val, new StepSliderConfig
			{
				min = min,
				max = max,
				increment = ((max > 120f) ? 5f : ((max > 3f) ? 1f : 0.05f))
			}));
			Track((ConfigEntryBase)(object)val);
			return val;
		}
	}
	internal sealed class MatchSettings
	{
		internal ItemSelection Selection;

		internal RespawnRule Respawn;

		internal bool OnStart;

		internal bool OnDeath;

		internal bool OnKill;

		internal bool OnTimer;

		internal bool AllowLevel;

		internal bool IncludeLunar;

		internal bool IncludeVoid;

		internal bool IncludeBoss;

		internal bool IncludeSpecial;

		internal bool IncludeEquipment;

		internal bool IncludeRestricted;

		internal bool Catchup;

		internal bool NoFallDamage;

		internal bool EnableScrapper;

		internal int StartingRewards;

		internal int DeathRewards;

		internal int KillRewards;

		internal int TimedRewards;

		internal int DraftSize;

		internal int KillLimit;

		internal int InitialCap;

		internal int CapStep;

		internal int MaximumLevel;

		internal int CommonWeight;

		internal int GreenWeight;

		internal int RedWeight;

		internal float ItemInterval;

		internal float RespawnSeconds;

		internal float ProtectionSeconds;

		internal float CapInterval;

		internal float MatchMinutes;

		internal float WarmupSeconds;

		internal float DamageScale;

		internal float HealOnKill;

		internal string BannedItems;

		internal string BannedEquipment;

		internal readonly EssenceWeights WeightedEssences;

		internal MatchSettings(ArenaConfig c)
		{
			Selection = c.Selection.Value;
			Respawn = c.Respawn.Value;
			OnStart = c.OnStart.Value;
			OnDeath = c.OnDeath.Value;
			OnKill = c.OnKill.Value;
			OnTimer = c.OnTimer.Value;
			AllowLevel = c.AllowLevel.Value;
			IncludeLunar = c.IncludeLunar.Value;
			IncludeVoid = c.IncludeVoid.Value;
			IncludeBoss = c.IncludeBoss.Value;
			IncludeSpecial = c.IncludeSpecial.Value;
			Catchup = c.Catchup.Value;
			IncludeEquipment = c.IncludeEquipment.Value;
			IncludeRestricted = c.IncludeRestricted.Value;
			EnableScrapper = c.EnableScrapper.Value;
			NoFallDamage = c.NoFallDamage.Value;
			StartingRewards = c.StartingRewards.Value;
			DeathRewards = c.DeathRewards.Value;
			KillRewards = c.KillRewards.Value;
			TimedRewards = c.TimedRewards.Value;
			DraftSize = c.DraftSize.Value;
			KillLimit = c.KillLimit.Value;
			InitialCap = c.InitialCap.Value;
			CapStep = c.CapStep.Value;
			MaximumLevel = c.MaximumLevel.Value;
			CommonWeight = c.CommonWeight.Value;
			GreenWeight = c.GreenWeight.Value;
			RedWeight = c.RedWeight.Value;
			WeightedEssences = new EssenceWeights(c.WhiteEssenceChance.Value, c.GreenEssenceChance.Value, c.RedEssenceChance.Value, c.VoidEssenceChance.Value, c.LunarEssenceChance.Value);
			ItemInterval = c.ItemInterval.Value;
			RespawnSeconds = c.RespawnSeconds.Value;
			ProtectionSeconds = c.ProtectionSeconds.Value;
			CapInterval = c.CapInterval.Value;
			MatchMinutes = c.MatchMinutes.Value;
			WarmupSeconds = c.WarmupSeconds.Value;
			DamageScale = c.DamageScale.Value;
			HealOnKill = c.HealOnKill.Value;
			BannedItems = c.BannedItems.Value;
			BannedEquipment = c.BannedEquipment.Value;
		}
	}
	internal static class ArenaDescriptions
	{
		internal static void BindPickup(MPButton button, PickupIndex index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			PickupDef pickupDef = PickupCatalog.GetPickupDef(index);
			if (pickupDef != null)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex);
				string text = (Object.op_Implicit((Object)(object)itemDef) ? itemDef.descriptionToken : (Object.op_Implicit((Object)(object)equipmentDef) ? equipmentDef.descriptionToken : pickupDef.pickupToken));
				string text2 = Language.GetString(text ?? "");
				if (string.IsNullOrEmpty(text2) || text2 == text)
				{
					text2 = Language.GetString(pickupDef.pickupToken ?? "");
				}
				BindText(button, Language.GetString(pickupDef.nameToken), text2, pickupDef.baseColor);
			}
		}

		internal static void BindText(MPButton button, string title, string body, Color color)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			if (Object.op_Implicit((Object)(object)button))
			{
				TooltipProvider val = ((Component)button).GetComponent<TooltipProvider>() ?? ((Component)button).gameObject.AddComponent<TooltipProvider>();
				TooltipProvider[] componentsInChildren = ((Component)button).GetComponentsInChildren<TooltipProvider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
				val.AllowTooltipOnNavigationSelect = false;
				val.SetContent(new TooltipContent
				{
					overrideTitleText = title,
					overrideBodyText = body,
					titleColor = ((color == Color.clear) ? Color.white : color),
					bodyColor = Color.white,
					disableTitleRichText = false,
					disableBodyRichText = false
				});
				(((Component)button).GetComponent<ArenaDescriptionTooltip>() ?? ((Component)button).gameObject.AddComponent<ArenaDescriptionTooltip>()).Bind(button, val);
			}
		}
	}
	[DefaultExecutionOrder(1000)]
	internal sealed class ArenaDescriptionTooltip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler, IUpdateSelectedHandler
	{
		private static ArenaDescriptionTooltip hovered;

		private MPButton button;

		private TooltipProvider provider;

		private bool selected;

		private Vector2 pointer;

		internal void Bind(MPButton owner, TooltipProvider content)
		{
			button = owner;
			provider = content;
			selected = false;
		}

		public void OnPointerEnter(PointerEventData data)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			hovered = this;
			pointer = data.position;
			Show(pointer);
		}

		public void OnPointerExit(PointerEventData data)
		{
			if ((Object)(object)hovered == (Object)(object)this)
			{
				hovered = null;
			}
			if (!selected)
			{
				Remove();
			}
		}

		public void OnSelect(BaseEventData data)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			selected = true;
			if (!Object.op_Implicit((Object)(object)hovered) || (Object)(object)hovered == (Object)(object)this)
			{
				Show(SelectionPosition());
			}
		}

		public void OnDeselect(BaseEventData data)
		{
			selected = false;
			if ((Object)(object)hovered != (Object)(object)this)
			{
				Remove();
			}
		}

		public void OnUpdateSelected(BaseEventData data)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			selected = true;
			if (!Object.op_Implicit((Object)(object)hovered) || (Object)(object)hovered == (Object)(object)this)
			{
				Show(((Object)(object)hovered == (Object)(object)this) ? pointer : SelectionPosition());
			}
		}

		private Vector2 SelectionPosition()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)this).transform;
			Canvas componentInParent = ((Component)this).GetComponentInParent<Canvas>();
			Camera obj = ((Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
			Rect rect = val.rect;
			return RectTransformUtility.WorldToScreenPoint(obj, ((Transform)val).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)));
		}

		private void Show(Vector2 position)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((!Plugin.Active && !ArenaLobby.Selected) || !Object.op_Implicit((Object)(object)button) || !Object.op_Implicit((Object)(object)button.eventSystem) || !Object.op_Implicit((Object)(object)provider))
			{
				return;
			}
			MPEventSystem eventSystem = button.eventSystem;
			TooltipController.SetTooltip(eventSystem, provider, position, (RectTransform)null);
			if (Object.op_Implicit((Object)(object)eventSystem.currentTooltip))
			{
				if (Object.op_Implicit((Object)(object)eventSystem.currentTooltip.titleLabel))
				{
					((TMP_Text)eventSystem.currentTooltip.titleLabel).text = provider.titleText;
				}
				if (Object.op_Implicit((Object)(object)eventSystem.currentTooltip.bodyLabel))
				{
					((TMP_Text)eventSystem.currentTooltip.bodyLabel).text = provider.bodyText;
				}
				Canvas component = ((Component)eventSystem.currentTooltip).GetComponent<Canvas>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.renderMode = (RenderMode)0;
					component.overrideSorting = true;
					component.sortingOrder = 30000;
				}
				((Transform)eventSystem.currentTooltip.tooltipCenterTransform).position = Vector2.op_Implicit(position);
			}
		}

		private void LateUpdate()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)button) || !Object.op_Implicit((Object)(object)button.eventSystem) || !Object.op_Implicit((Object)(object)provider))
			{
				return;
			}
			if ((Object)(object)hovered == (Object)(object)this)
			{
				Vector2 val = default(Vector2);
				if (button.eventSystem.GetCursorPosition(ref val))
				{
					pointer = val;
				}
				Show(pointer);
			}
			else if (selected && !Object.op_Implicit((Object)(object)hovered))
			{
				Show(SelectionPosition());
			}
		}

		private void Remove()
		{
			if (Object.op_Implicit((Object)(object)provider))
			{
				TooltipController.RemoveTooltip(provider);
			}
		}

		private void OnDisable()
		{
			if ((Object)(object)hovered == (Object)(object)this)
			{
				hovered = null;
			}
			selected = false;
			Remove();
		}

		private void OnDestroy()
		{
			if ((Object)(object)hovered == (Object)(object)this)
			{
				hovered = null;
			}
			Remove();
		}
	}
	[HarmonyPatch(typeof(PickupPickerPanel), "UpdateButtonUI")]
	internal static class ArenaNativePickerDescriptions
	{
		private static void Postfix(PickupPickerPanel __instance, int index, Option[] ___pickupOptions, UIElementAllocator<MPButton> ___buttonAllocator)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Invalid comparison between Unknown and I4
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Invalid comparison between Unknown and I4
			if (!Plugin.Active || ___pickupOptions == null || ___buttonAllocator == null || index < 0 || index >= ___pickupOptions.Length || index >= ___buttonAllocator.elements.Count)
			{
				return;
			}
			if (index == 0)
			{
				TMP_Text[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TMP_Text>(true);
				foreach (TMP_Text val in componentsInChildren)
				{
					LanguageTextMeshController component = ((Component)val).GetComponent<LanguageTextMeshController>();
					if (val.text == "Cancel" || (Object.op_Implicit((Object)(object)component) && (component.token ?? "").ToUpperInvariant().Contains("CANCEL")))
					{
						if (Object.op_Implicit((Object)(object)component))
						{
							((Behaviour)component).enabled = false;
						}
						val.text = "Back";
					}
				}
			}
			PickupIndex pickupIndex = ___pickupOptions[index].pickup.pickupIndex;
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (pickupDef != null && ((int)pickupDef.itemIndex != -1 || (int)pickupDef.equipmentIndex != -1))
			{
				ArenaDescriptions.BindPickup(___buttonAllocator.elements[index], pickupIndex);
			}
		}
	}
	[Serializable]
	internal sealed class HostRuleView
	{
		public string Group;

		public string Name;

		public string Description;

		public string Value;
	}
	[Serializable]
	internal sealed class HostSettingsView
	{
		public uint Revision;

		public HostRuleView[] Rules;
	}
	internal sealed class HostSettingsRequest : MessageBase
	{
		internal uint UserId;

		internal uint KnownRevision;

		public override void Serialize(NetworkWriter writer)
		{
			writer.Write(UserId);
			writer.Write(KnownRevision);
		}

		public override void Deserialize(NetworkReader reader)
		{
			UserId = reader.ReadUInt32();
			KnownRevision = reader.ReadUInt32();
		}
	}
	internal static class ArenaHostSettings
	{
		internal const short RequestId = 28676;

		internal const short ViewId = 28677;

		internal static HostSettingsView ClientView;

		private static readonly Dictionary<uint, float> lastRequests = new Dictionary<uint, float>();

		private static uint cachedRevision;

		private static string cachedJson;

		internal static string Id(ConfigEntryBase entry)
		{
			return entry.Definition.Section + "/" + entry.Definition.Key;
		}

		internal static string Value(ConfigEntryBase entry)
		{
			return Convert.ToString(entry.BoxedValue, CultureInfo.InvariantCulture) ?? "";
		}

		internal static HostSettingsView Capture()
		{
			return new HostSettingsView
			{
				Revision = Plugin.Settings.MatchRevision,
				Rules = Plugin.Settings.MatchEntries.Select((ConfigEntryBase e) => new HostRuleView
				{
					Group = e.Definition.Section,
					Name = e.Definition.Key,
					Description = e.Description.Description,
					Value = Value(e)
				}).ToArray()
			};
		}

		internal static bool TryEdit(ConfigEntryBase entry, string value)
		{
			if (!NetworkServer.active || !ArenaLobby.Selected || entry == null || !Plugin.Settings.MatchEntries.Contains(entry))
			{
				return false;
			}
			try
			{
				object boxedValue;
				if (entry.SettingType == typeof(bool))
				{
					boxedValue = bool.Parse(value);
				}
				else if (entry.SettingType == typeof(int))
				{
					boxedValue = int.Parse(value.Trim().TrimEnd('%'), NumberStyles.Integer, CultureInfo.InvariantCulture);
				}
				else if (entry.SettingType == typeof(float))
				{
					float num = float.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture);
					if (float.IsNaN(num) || float.IsInfinity(num))
					{
						return false;
					}
					boxedValue = num;
				}
				else if (entry.SettingType.IsEnum)
				{
					boxedValue = Enum.Parse(entry.SettingType, value);
				}
				else
				{
					if (!(entry.SettingType == typeof(string)))
					{
						return false;
					}
					boxedValue = value;
				}
				entry.BoxedValue = boxedValue;
				return true;
			}
			catch (FormatException)
			{
				return false;
			}
			catch (OverflowException)
			{
				return false;
			}
			catch (ArgumentException)
			{
				return false;
			}
		}

		internal static void Request(NetworkUser user)
		{
			//IL_0059: 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)
			if (ArenaLobby.Selected && !NetworkServer.active && Object.op_Implicit((Object)(object)user) && user.localUser != null)
			{
				NetworkClient val = ((IEnumerable<NetworkClient>)NetworkClient.allClients).FirstOrDefault((Func<NetworkClient, bool>)((NetworkClient c) => c != null && c.isConnected));
				if (val != null)
				{
					HostSettingsRequest hostSettingsRequest = new HostSettingsRequest();
					NetworkInstanceId netId = ((NetworkBehaviour)user).netId;
					hostSettingsRequest.UserId = ((NetworkInstanceId)(ref netId)).Value;
					hostSettingsRequest.KnownRevision = ((ClientView != null) ? ClientView.Revision : 0u);
					val.Send((short)28676, (MessageBase)(object)hostSettingsRequest);
				}
			}
		}

		internal static void ReceiveRequest(NetworkMessage message)
		{
			if (!NetworkServer.active || !ArenaLobby.Selected || message.conn == null)
			{
				return;
			}
			try
			{
				HostSettingsRequest request = message.ReadMessage<HostSettingsRequest>();
				NetworkUser val = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)delegate(NetworkUser u)
				{
					//IL_0009: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					if (Object.op_Implicit((Object)(object)u))
					{
						NetworkInstanceId netId = ((NetworkBehaviour)u).netId;
						return ((NetworkInstanceId)(ref netId)).Value == request.UserId;
					}
					return false;
				});
				if (!Object.op_Implicit((Object)(object)val) || ((NetworkBehaviour)val).connectionToClient != message.conn || (lastRequests.TryGetValue(request.UserId, out var value) && Time.unscaledTime - value < 0.25f))
				{
					return;
				}
				lastRequests[request.UserId] = Time.unscaledTime;
				if (request.KnownRevision != Plugin.Settings.MatchRevision)
				{
					if (cachedJson == null || cachedRevision != Plugin.Settings.MatchRevision)
					{
						cachedJson = JsonUtility.ToJson((object)Capture());
						cachedRevision = Plugin.Settings.MatchRevision;
					}
					if (cachedJson.Length < 60000)
					{
						message.conn.Send((short)28677, (MessageBase)(object)new SnapshotMessage
						{
							Json = cachedJson
						});
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("Host settings read request was ignored: " + ex.Message);
			}
		}

		internal static void ReceiveView(NetworkMessage message)
		{
			if (NetworkServer.active || !ArenaLobby.Selected)
			{
				return;
			}
			try
			{
				string json = message.ReadMessage<SnapshotMessage>().Json;
				if (!string.IsNullOrEmpty(json) && json.Length <= 60000)
				{
					HostSettingsView hostSettingsView = JsonUtility.FromJson<HostSettingsView>(json);
					if (hostSettingsView != null && hostSettingsView.Rules != null && hostSettingsView.Rules.Length <= 128 && !hostSettingsView.Rules.Any((HostRuleView r) => r == null || !ArenaRules.IsMatchSettingGroup(r.Group) || string.IsNullOrEmpty(r.Name) || r.Name.Length > 128 || (r.Value ?? "").Length > 16384 || (r.Description ?? "").Length > 4096))
					{
						ClientView = hostSettingsView;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void Clear()
		{
			ClientView = null;
			cachedJson = null;
			cachedRevision = 0u;
			lastRequests.Clear();
		}
	}
	internal sealed class ArenaHudPanel : MonoBehaviour
	{
		private GameObject root;

		private TMP_Text text;

		private LayoutElement layout;

		internal void Clear()
		{
			if (Object.op_Implicit((Object)(object)root))
			{
				root.SetActive(false);
				Object.Destroy((Object)(object)root);
			}
			root = null;
		}

		private void OnDestroy()
		{
			Clear();
		}

		internal void Show(MatchView view, NetworkUser user)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_013a: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0662: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_069e: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Active || view == null || !Object.op_Implicit((Object)(object)user) || user.localUser == null || !Object.op_Implicit((Object)(object)user.localUser.cameraRigController))
			{
				Clear();
				return;
			}
			HUD hud = user.localUser.cameraRigController.hud;
			if (!Object.op_Implicit((Object)(object)hud))
			{
				return;
			}
			VerticalLayoutGroup val = ((IEnumerable<VerticalLayoutGroup>)((Component)hud).GetComponentsInChildren<VerticalLayoutGroup>(true)).FirstOrDefault((Func<VerticalLayoutGroup, bool>)((VerticalLayoutGroup g) => ((Object)g).name == "RightInfoBar"));
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Rect rect;
			if (!Object.op_Implicit((Object)(object)root) || (Object)(object)root.transform.parent != (Object)(object)((Component)val).transform)
			{
				Clear();
				root = new GameObject("RiskOfArena Leaderboard", new Type[3]
				{
					typeof(RectTransform),
					typeof(Image),
					typeof(LayoutElement)
				});
				root.transform.SetParent(((Component)val).transform, false);
				((Graphic)root.GetComponent<Image>()).color = new Color(0.035f, 0.06f, 0.075f, 0.6f);
				((Graphic)root.GetComponent<Image>()).raycastTarget = false;
				ArenaStyle.Border(root, new Color(0.65f, 0.9f, 0.6f, 0.45f));
				layout = root.GetComponent<LayoutElement>();
				layout.minHeight = 110f;
				layout.flexibleHeight = 0f;
				rect = ((RectTransform)((Component)val).transform).rect;
				float num = Mathf.Max(140f, ((Rect)(ref rect)).width);
				root.GetComponent<RectTransform>().SetSizeWithCurrentAnchors((Axis)0, num);
				layout.preferredWidth = num;
				GameObject val2 = new GameObject("Arena standings", new Type[2]
				{
					typeof(RectTransform),
					typeof(HGTextMeshProUGUI)
				});
				val2.transform.SetParent(root.transform, false);
				this.text = (TMP_Text)(object)val2.GetComponent<HGTextMeshProUGUI>();
				this.text.fontSize = 12f;
				this.text.alignment = (TextAlignmentOptions)257;
				((Graphic)this.text).color = Color.white;
				((Graphic)this.text).raycastTarget = false;
				ArenaStyle.Fill(this.text.rectTransform, 8f, 7f, 8f, 7f);
			}
			if (Object.op_Implicit((Object)(object)HGTextMeshProUGUI.defaultLanguageFont) && (Object)(object)this.text.font != (Object)(object)HGTextMeshProUGUI.defaultLanguageFont)
			{
				this.text.font = HGTextMeshProUGUI.defaultLanguageFont;
			}
			root.SetActive(true);
			root.transform.SetAsLastSibling();
			PlayerView playerView = view.Players.FirstOrDefault((PlayerView p) => p.UserId == view.UserId);
			StringBuilder stringBuilder = new StringBuilder("<b>RiskOfArena</b>\n");
			stringBuilder.Append(view.Finished ? "Match complete" : ((view.Warmup > 0f) ? ("Warmup " + Clock(view.Warmup)) : ("Match " + Clock(view.Elapsed))));
			if (view.KillLimit > 0)
			{
				stringBuilder.Append(" · first to ").Append(view.KillLimit);
			}
			stringBuilder.Append("\nLevel cap ").Append(view.Cap);
			object obj;
			if (view.Selection != 3)
			{
				ItemSelection selection = (ItemSelection)view.Selection;
				obj = selection.ToString();
			}
			else
			{
				obj = "Weighted Essence";
			}
			string value = (string)obj;
			stringBuilder.Append("\n").Append(value).Append(" · rewards ")
				.Append(view.Pending);
			if (playerView != null && playerView.Dead)
			{
				stringBuilder.Append("\n").Append(view.WaitingChoice ? "Choose a reward to respawn" : ("Respawn " + Clock(view.Respawn)));
			}
			if (view.TimerEnabled && !view.Finished)
			{
				stringBuilder.Append("\nNext reward ").Append(Clock(view.NextReward));
			}
			stringBuilder.Append("\n\n<b>LEADERBOARD · K / D</b>");
			int num2 = 0;
			foreach (PlayerView item in from p in view.Players
				orderby p.Kills descending, p.Deaths
				select p)
			{
				string text = item.Name.Replace("<", "‹").Replace(">", "›");
				if (text.Length > 18)
				{
					text = text.Substring(0, 17) + "…";
				}
				stringBuilder.Append("\n").Append((item.UserId == view.UserId) ? "<color=#A5FF7C>" : "").Append(++num2)
					.Append(". ")
					.Append(text)
					.Append("  ")
					.Append(item.Kills)
					.Append(" / ")
					.Append(item.Deaths)
					.Append((item.UserId == view.UserId) ? "</color>" : "");
			}
			stringBuilder.Append("\n<size=10>").Append(Plugin.Settings.PickerKey.Value).Append(" rewards · ")
				.Append(Plugin.Settings.BoardKey.Value)
				.Append(" full scores</size>");
			this.text.text = stringBuilder.ToString();
			rect = ((RectTransform)((Component)val).transform).rect;
			float num3 = Mathf.Max(120f, ((Rect)(ref rect)).width - 16f);
			float num4 = this.text.GetPreferredValues(this.text.text, num3, 0f).y + 14f;
			if (Mathf.Abs(layout.preferredHeight - num4) > 0.1f)
			{
				layout.preferredHeight = num4;
			}
		}

		private static string Clock(float value)
		{
			int num = Mathf.CeilToInt(Mathf.Max(0f, value));
			return (num / 60).ToString("00") + ":" + (num % 60).ToString("00");
		}
	}
	[Serializable]
	internal sealed class MapView
	{
		public int Index;

		public int Votes;

		public string Name;

		public string InternalName;
	}
	[Serializable]
	internal sealed class LobbyView
	{
		public uint UserId;

		public int VotedMap = -1;

		public int SelectedMap = -1;

		public MapView[] Maps = new MapView[0];
	}
	internal sealed class VoteMessage : MessageBase
	{
		internal uint UserId;

		internal int Map;

		public override void Serialize(NetworkWriter writer)
		{
			writer.Write(UserId);
			writer.Write(Map);
		}

		public override void Deserialize(NetworkReader reader)
		{
			UserId = reader.ReadUInt32();
			Map = reader.ReadInt32();
		}
	}
	internal sealed class ArenaLobby : MonoBehaviour
	{
		internal static ArenaLobby Instance;

		internal static readonly Dictionary<uint, LobbyView> Views = new Dictionary<uint, LobbyView>();

		internal const short VoteId = 28674;

		internal const short LobbyId = 28675;

		private readonly Dictionary<NetworkUserId, int> votes = new Dictionary<NetworkUserId, int>();

		private readonly Dictionary<NetworkUserId, float> lastVotes = new Dictionary<NetworkUserId, float>();

		private readonly List<int> eligible = new List<int>();

		private float nextUpdate;

		private bool previouslySelected;

		private SceneDef lockedMap;

		private bool mapCacheValid;

		private string cachedBlacklist;

		private int cachedSceneCount;

		private RuleBook cachedBook;

		private MapView[] mapDefinitions = new MapView[0];

		internal static bool Selected
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				if ((int)Plugin.ArenaDifficulty != -1 && Object.op_Implicit((Object)(object)PreGameController.instance))
				{
					return PreGameController.instance.readOnlyRuleBook.FindDifficulty() == Plugin.ArenaDifficulty;
				}
				return false;
			}
		}

		private void Awake()
		{
			Instance = this;
			Language.onCurrentLanguageChanged += InvalidateMaps;
		}

		private void OnDestroy()
		{
			Language.onCurrentLanguageChanged -= InvalidateMaps;
			Instance = null;
			Views.Clear();
		}

		private void InvalidateMaps()
		{
			mapCacheValid = false;
		}

		internal void ResetAfterRun()
		{
			votes.Clear();
			lastVotes.Clear();
			eligible.Clear();
			lockedMap = null;
			Views.Clear();
			mapCacheValid = false;
			mapDefinitions = new MapView[0];
			ArenaHostSettings.Clear();
		}

		private void Update()
		{
			if (!NetworkServer.active || Time.unscaledTime < nextUpdate)
			{
				return;
			}
			nextUpdate = Time.unscaledTime + 0.4f;
			if (Selected)
			{
				if (!previouslySelected)
				{
					ResetAfterRun();
				}
				previouslySelected = true;
				RefreshMaps();
				SendViews();
			}
			else if (Object.op_Implicit((Object)(object)PreGameController.instance))
			{
				if (previouslySelected)
				{
					ResetAfterRun();
				}
				previouslySelected = false;
			}
		}

		internal void RefreshMaps()
		{
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Expected O, but got Unknown
			RuleBook val = (Object.op_Implicit((Object)(object)PreGameController.instance) ? PreGameController.instance.readOnlyRuleBook : (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.ruleBook : null));
			string value = Plugin.Settings.MapBlacklist.Value;
			if (mapCacheValid && cachedBlacklist == value && cachedSceneCount == SceneCatalog.sceneDefCount && val != null && cachedBook.Equals(val))
			{
				return;
			}
			eligible.Clear();
			HashSet<string> hashSet = new HashSet<string>(from x in value.Split(',')
				select x.Trim(), StringComparer.OrdinalIgnoreCase);
			for (int num = 0; num < SceneCatalog.sceneDefCount; num++)
			{
				SceneDef sceneDef = SceneCatalog.GetSceneDef((SceneIndex)num);
				if (ArenaStages.Playable(sceneDef) && !hashSet.Contains(sceneDef.cachedName) && !hashSet.Contains(sceneDef.baseSceneName) && !hashSet.Contains(Language.GetString(sceneDef.nameToken)) && (!Object.op_Implicit((Object)(object)sceneDef.requiredExpansion) || (val != null && sceneDef.requiredExpansion.enabledChoice != null && val.IsChoiceActive(sceneDef.requiredExpansion.enabledChoice))))
				{
					eligible.Add(num);
				}
			}
			NetworkUserId[] array = votes.Keys.ToArray();
			foreach (NetworkUserId key in array)
			{
				if (!eligible.Contains(votes[key]))
				{
					votes.Remove(key);
				}
			}
			mapDefinitions = (from i in eligible
				select new MapView
				{
					Index = i,
					InternalName = SceneCatalog.GetSceneDef((SceneIndex)i).cachedName,
					Name = Language.GetString(SceneCatalog.GetSceneDef((SceneIndex)i).nameToken)
				} into m
				orderby m.Name, m.InternalName
				select m).ToArray();
			if (val != null)
			{
				if (cachedBook == null)
				{
					cachedBook = new RuleBook();
				}
				cachedBook.Copy(val);
			}
			cachedBlacklist = value;
			cachedSceneCount = SceneCatalog.sceneDefCount;
			mapCacheValid = val != null;
		}

		internal bool HasMaps()
		{
			RefreshMaps();
			return eligible.Count > 0;
		}

		internal SceneDef LockWinner()
		{
			if (Object.op_Implicit((Object)(object)lockedMap))
			{
				return lockedMap;
			}
			RefreshMaps();
			HashSet<NetworkUserId> connected = new HashSet<NetworkUserId>(from u in NetworkUser.readOnlyInstancesList.Where(ArenaNetwork.IsUserPresent)
				select u.id);
			int num = MapVotingRules.Preview(eligible.ToArray(), (from v in votes
				where connected.Contains(v.Key)
				select v.Value).ToArray(), DefaultMapIndex());
			if (num < 0)
			{
				return null;
			}
			lockedMap = SceneCatalog.GetSceneDef((SceneIndex)num);
			Plugin.Log("Arena map vote selected " + lockedMap.cachedName + ".");
			return lockedMap;
		}

		internal void Vote(NetworkUser user, int index)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (Selected && NetworkServer.active && ArenaNetwork.IsUserPresent(user))
			{
				RefreshMaps();
				if (eligible.Contains(index) && (!lastVotes.TryGetValue(user.id, out var value) || !(Time.unscaledTime - value < 0.15f)))
				{
					lastVotes[user.id] = Time.unscaledTime;
					votes[user.id] = index;
					SendViews();
				}
			}
		}

		private void SendViews()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser[] array = NetworkUser.readOnlyInstancesList.Where(ArenaNetwork.IsUserPresent).ToArray();
			HashSet<NetworkUserId> identities = new HashSet<NetworkUserId>(array.Select((NetworkUser u) => u.id));
			int selectedMap = MapVotingRules.Preview(eligible.ToArray(), (from v in votes
				where identities.Contains(v.Key)
				select v.Value).ToArray(), DefaultMapIndex());
			Dictionary<int, int> counts = new Dictionary<int, int>();
			foreach (KeyValuePair<NetworkUserId, int> vote in votes)
			{
				if (identities.Contains(vote.Key))
				{
					counts.TryGetValue(vote.Value, out var value);
					counts[vote.Value] = value + 1;
				}
			}
			MapView[] maps = mapDefinitions.Select((MapView definition) => new MapView
			{
				Index = definition.Index,
				InternalName = definition.InternalName,
				Name = definition.Name,
				Votes = (counts.ContainsKey(definition.Index) ? counts[definition.Index] : 0)
			}).ToArray();
			NetworkUser[] array2 = array;
			foreach (NetworkUser val in array2)
			{
				LobbyView lobbyView = new LobbyView();
				NetworkInstanceId netId = ((NetworkBehaviour)val).netId;
				lobbyView.UserId = ((NetworkInstanceId)(ref netId)).Value;
				lobbyView.VotedMap = (votes.TryGetValue(val.id, out var value2) ? value2 : (-1));
				lobbyView.SelectedMap = selectedMap;
				lobbyView.Maps = maps;
				LobbyView lobbyView2 = lobbyView;
				if (val.localUser != null)
				{
					Dictionary<uint, LobbyView> views = Views;
					netId = ((NetworkBehaviour)val).netId;
					views[((NetworkInstanceId)(ref netId)).Value] = lobbyView2;
				}
				else
				{
					((NetworkBehaviour)val).connectionToClient.Send((short)28675, (MessageBase)(object)new SnapshotMessage
					{
						Json = JsonUtility.ToJson((object)lobbyView2)
					});
				}
			}
		}

		private int DefaultMapIndex()
		{
			string a = (Plugin.Settings.DefaultMap.Value ?? "").Trim();
			foreach (int item in eligible)
			{
				SceneDef sceneDef = SceneCatalog.GetSceneDef((SceneIndex)item);
				if (string.Equals(a, sceneDef.cachedName, StringComparison.OrdinalIgnoreCase) || string.Equals(a, sceneDef.baseSceneName, StringComparison.OrdinalIgnoreCase) || string.Equals(a, Language.GetString(sceneDef.nameToken), StringComparison.OrdinalIgnoreCase))
				{
					return item;
				}
			}
			if (eligible.Count != 0)
			{
				return eligible[0];
			}
			return -1;
		}

		internal static void ReceiveVote(NetworkMessage message)
		{
			if (!Selected || !NetworkServer.active || !Object.op_Implicit((Object)(object)Instance))
			{
				return;
			}
			try
			{
				VoteMessage request = message.ReadMessage<VoteMessage>();
				NetworkUser val = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)delegate(NetworkUser u)
				{
					//IL_0009: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					if (Object.op_Implicit((Object)(object)u))
					{
						NetworkInstanceId netId = ((NetworkBehaviour)u).netId;
						return ((NetworkInstanceId)(ref netId)).Value == request.UserId;
					}
					return false;
				});
				if (Object.op_Implicit((Object)(object)val) && ((NetworkBehaviour)val).connectionToClient == message.conn)
				{
					Instance.Vote(val, request.Map);
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void ReceiveView(NetworkMessage message)
		{
			if (!Selected)
			{
				return;
			}
			try
			{
				LobbyView lobbyView = JsonUtility.FromJson<LobbyView>(message.ReadMessage<SnapshotMessage>().Json);
				if (lobbyView != null && lobbyView.Maps != null && lobbyView.Maps.Length <= 512)
				{
					Views[lobbyView.UserId] = lobbyView;
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void Submit(NetworkUser user, int map)
		{
			//IL_0072: 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)
			if (!Selected || !Object.op_Implicit((Object)(object)user) || user.localUser == null)
			{
				return;
			}
			if (NetworkServer.active)
			{
				if (Object.op_Implicit((Object)(object)Instance))
				{
					Instance.Vote(user, map);
				}
				return;
			}
			NetworkClient val = ((IEnumerable<NetworkClient>)NetworkClient.allClients).FirstOrDefault((Func<NetworkClient, bool>)((NetworkClient c) => c != null && c.isConnected));
			if (val != null)
			{
				VoteMessage voteMessage = new VoteMessage();
				NetworkInstanceId netId = ((NetworkBehaviour)user).netId;
				voteMessage.UserId = ((NetworkInstanceId)(ref netId)).Value;
				voteMessage.Map = map;
				val.Send((short)28674, (MessageBase)(object)voteMessage);
			}
		}
	}
	internal sealed class ArenaLobbyOptions : MonoBehaviour
	{
		private sealed class Row
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static UnityAction <>9__9_0;

				internal void <.ctor>b__9_0()
				{
				}
			}

			internal HostRuleView Rule;

			private readonly ArenaLobbyOptions owner;

			private readonly ConfigEntryBase entry;

			private readonly TooltipProvider tooltip;

			private TMP_Text value;

			private TMP_InputField input;

			private Slider slider;

			private MPButton action;

			private bool refreshing;

			internal Row(ArenaLobbyOptions owner, HostRuleView rule, ConfigEntryBase entry)
			{
				//IL_00b0: 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)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_0110: 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_0059: Expected O, but got Unknown
				//IL_01da: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: 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
				this.owner = owner;
				Rule = rule;
				this.entry = entry;
				RectTransform content = owner.content;
				string name = rule.Name;
				object obj = <>c.<>9__9_0;
				if (obj == null)
				{
					UnityAction val = delegate
					{
					};
					<>c.<>9__9_0 = val;
					obj = (object)val;
				}
				MPButton val2 = owner.Button((Transform)(object)content, name, (UnityAction)obj);
				LayoutElement obj2 = ((Component)val2).gameObject.AddComponent<LayoutElement>();
				obj2.minHeight = (obj2.preferredHeight = 88f);
				obj2.flexibleHeight = 0f;
				TMP_Text val3 = ((Component)val2).GetComponentsInChildren<TMP_Text>(true).First();
				val3.alignment = (TextAlignmentOptions)4097;
				val3.rectTransform.anchorMin = new Vector2(0.02f, 0f);
				val3.rectTransform.anchorMax = new Vector2(0.46f, 1f);
				val3.rectTransform.offsetMin = (val3.rectTransform.offsetMax = Vector2.zero);
				ArenaDescriptions.BindText(val2, rule.Name, rule.Description, new Color(0.7f, 0.95f, 0.65f));
				tooltip = ((Component)val2).GetComponent<TooltipProvider>();
				if (entry == null)
				{
					value = owner.Label(((Component)val2).transform, rule.Value, 18f);
					value.richText = false;
					Area(value.rectTransform, 0.48f, 0.98f);
					value.enableAutoSizing = true;
					value.fontSizeMin = 12f;
					value.fontSizeMax = 18f;
				}
				else if ((object)entry == Plugin.Settings.MapBlacklist || (object)entry == Plugin.Settings.DefaultMap)
				{
					action = owner.Button(((Component)val2).transform, "Choose stages", (UnityAction)delegate
					{
						if (NetworkServer.active && ArenaLobby.Selected)
						{
							ArenaStageSettings.Open((object)entry == Plugin.Settings.MapBlacklist, hostOnly: true);
						}
					});
					Area(((Component)action).GetComponent<RectTransform>(), 0.49f, 0.98f);
					value = ((Component)action).GetComponentInChildren<TMP_Text>();
				}
				else if (entry.SettingType == typeof(bool) || entry.SettingType.IsEnum)
				{
					action = owner.Button(((Component)val2).transform, "", new UnityAction(Cycle));
					Area(((Component)action).GetComponent<RectTransform>(), 0.49f, 0.98f);
					value = ((Component)action).GetComponentInChildren<TMP_Text>();
				}
				else
				{
					bool flag = entry.SettingType == typeof(int) || entry.SettingType == typeof(float);
					input = Input(((Component)val2).transform, flag);
					if (flag)
					{
						CreateSlider(((Component)val2).transform);
					}
				}
				Refresh();
			}

			private void Cycle()
			{
				string text;
				if (entry.SettingType == typeof(bool))
				{
					text = (!(bool)entry.BoxedValue).ToString();
				}
				else
				{
					string[] names = Enum.GetNames(entry.SettingType);
					text = names[(Array.IndexOf<string>(names, entry.BoxedValue.ToString()) + 1) % names.Length];
				}
				ArenaHostSettings.TryEdit(entry, text);
				Refresh();
			}

			private TMP_InputField Input(Transform parent, bool number)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Expected O, but got Unknown
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: 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)
				GameObject val = new GameObject("Value", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val.transform.SetParent(parent, false);
				RectTransform component = val.GetComponent<RectTransform>();
				Area(component, 0.49f, 0.98f);
				if (number)
				{
					component.anchorMin = new Vector2(0.75f, 0.54f);
					component.anchorMax = new Vector2(0.98f, 0.94f);
					Vector2 offsetMin = (component.offsetMax = Vector2.zero);
					component.offsetMin = offsetMin;
				}
				((Graphic)val.GetComponent<Image>()).color = new Color(0.08f, 0.12f, 0.15f, 0.85f);
				ArenaStyle.Border(val, new Color(0.6f, 0.75f, 0.8f, 0.6f));
				GameObject val2 = new GameObject("Text viewport", new Type[2]
				{
					typeof(RectTransform),
					typeof(RectMask2D)
				});
				val2.transform.SetParent(val.transform, false);
				ArenaStyle.Fill(val2.GetComponent<RectTransform>(), 8f, 4f, 8f, 4f);
				TMP_Text val3 = owner.Label(val2.transform, "", 19f);
				val3.richText = false;
				ArenaStyle.Fill(val3.rectTransform);
				TMP_InputField obj = val.AddComponent<TMP_InputField>();
				((Selectable)obj).targetGraphic = (Graphic)(object)val.GetComponent<Image>();
				obj.textViewport = val2.GetComponent<RectTransform>();
				obj.textComponent = val3;
				obj.contentType = (ContentType)(number ? ((entry.SettingType == typeof(int)) ? 2 : 3) : 0);
				obj.lineType = (LineType)0;
				((UnityEvent<string>)(object)obj.onEndEdit).AddListener((UnityAction<string>)delegate(string text)
				{
					if (!refreshing)
					{
						ArenaHostSettings.TryEdit(entry, text);
						Refresh();
					}
				});
				return obj;
			}

			private void CreateSlider(Transform parent)
			{
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Expected O, but got Unknown
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_0156: Expected O, but got Unknown
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				AcceptableValueRange<int> integers = entry.Description.AcceptableValues as AcceptableValueRange<int>;
				AcceptableValueRange<float> val = entry.Description.AcceptableValues as AcceptableValueRange<float>;
				float min;
				float max;
				if (integers != null)
				{
					min = integers.MinValue;
					max = integers.MaxValue;
				}
				else
				{
					if (val == null)
					{
						return;
					}
					min = val.MinValue;
					max = val.MaxValue;
				}
				GameObject val2 = new GameObject("Amount slider", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val2.transform.SetParent(parent, false);
				RectTransform component = val2.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 0.12f);
				component.anchorMax = new Vector2(0.97f, 0.4f);
				Vector2 offsetMin = (component.offsetMax = Vector2.zero);
				component.offsetMin = offsetMin;
				((Graphic)val2.GetComponent<Image>()).color = new Color(0.2f, 0.3f, 0.33f, 0.8f);
				GameObject val3 = new GameObject("Handle", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val3.transform.SetParent(val2.transform, false);
				RectTransform component2 = val3.GetComponent<RectTransform>();
				component2.sizeDelta = new Vector2(16f, 0f);
				((Graphic)val3.GetComponent<Image>()).color = new Color(0.7f, 0.95f, 0.65f);
				slider = val2.AddComponent<Slider>();
				slider.minValue = min;
				slider.maxValue = max;
				slider.wholeNumbers = integers != null;
				slider.handleRect = component2;
				((Selectable)slider).targetGraphic = (Graphic)(object)val3.GetComponent<Image>();
				((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float amount)
				{
					if (!refreshing)
					{
						float num = ((integers != null) ? 1f : ((max > 120f) ? 5f : ((max > 3f) ? 1f : 0.05f)));
						float num2 = Mathf.Clamp(Mathf.Round(amount / num) * num, min, max);
						ArenaHostSettings.TryEdit(entry, num2.ToString("0.####", CultureInfo.InvariantCulture));
						Refresh();
					}
				});
			}

			internal void Refresh()
			{
				refreshing = true;
				string text = ((entry == null) ? Rule.Value : ArenaHostSettings.Value(entry));
				if (Object.op_Implicit((Object)(object)tooltip))
				{
					tooltip.overrideBodyText = Rule.Description + ((entry == null) ? ("\n\nHost value:\n" + text) : "");
				}
				if (Object.op_Implicit((Object)(object)value))
				{
					if ((object)entry == Plugin.Settings.MapBlacklist)
					{
						value.text = "Choose blacklisted stages";
					}
					else if ((object)entry == Plugin.Settings.DefaultMap)
					{
						value.text = "Choose default · " + text;
					}
					else
					{
						value.text = ((text == "True") ? "On" : ((text == "False") ? "Off" : text));
					}
				}
				if (Object.op_Implicit((Object)(object)input) && !input.isFocused)
				{
					input.text = text;
				}
				if (Object.op_Implicit((Object)(object)slider))
				{
					slider.SetValueWithoutNotify(Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture));
				}
				bool interactable = entry == null || !entry.Definition.Key.EndsWith("essence chance", StringComparison.Ordinal) || Plugin.Settings.Selection.Value == ItemSelection.WeightedEssence;
				if (Object.op_Implicit((Object)(object)action))
				{
					((Selectable)action).interactable = interactable;
				}
				if (Object.op_Implicit((Object)(object)input))
				{
					((Selectable)input).interactable = interactable;
				}
				if (Object.op_Implicit((Object)(object)slider))
				{
					((Selectable)slider).interactable = interactable;
				}
				refreshing = false;
			}

			private static void Area(RectTransform rect, float left, float right)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: 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_0030: Unknown result type (might be due to invalid IL or missing references)
				rect.anchorMin = new Vector2(left, 0.12f);
				rect.anchorMax = new Vector2(right, 0.88f);
				Vector2 offsetMin = (rect.offsetMax = Vector2.zero);
				rect.offsetMin = offsetMin;
			}
		}

		private static ArenaLobbyOptions instance;

		private MPEventSystem eventSystem;

		private GameObject previousSelection;

		private GameObject panel;

		private TMP_FontAsset font;

		private TMP_Text status;

		private RectTransform categoryList;

		private RectTransform content;

		private ScrollRect scroll;

		private HostSettingsView view;

		private bool host;

		private uint revision;

		private float nextRequest;

		private float nextRefresh;

		private string group;

		private readonly Dictionary<string, ConfigEntryBase> entries = new Dictionary<string, ConfigEntryBase>();

		private readonly Dictionary<string, Row> rows = new Dictionary<string, Row>();

		private readonly List<MPButton> categoryButtons = new List<MPButton>();

		private MPButton back;

		internal static bool IsOpen => Object.op_Implicit((Object)(object)instance);

		internal static void Open(MPButton source)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (!ArenaLobby.Selected || Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.eventSystem))
			{
				return;
			}
			GameObject val = new GameObject("RiskOfArena Match Settings", new Type[6]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster),
				typeof(MPEventSystemProvider),
				typeof(Image)
			});
			Canvas component = val.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 160;
			CanvasScaler component2 = val.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1920f, 1080f);
			component2.matchWidthOrHeight = 0.5f;
			((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.55f);
			MPEventSystemProvider component3 = val.GetComponent<MPEventSystemProvider>();
			component3.eventSystem = source.eventSystem;
			component3.fallBackToMainEventSystem = false;
			val.AddComponent<MPEventSystemLocator>();
			instance = val.AddComponent<ArenaLobbyOptions>();
			instance.eventSystem = source.eventSystem;
			instance.previousSelection = ((EventSystem)source.eventSystem).currentSelectedGameObject;
			instance.host = NetworkServer.active;
			TMP_Text val2 = ((IEnumerable<TMP_Text>)((Component)source).GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text t) => Object.op_Implicit((Object)(object)t.font)));
			instance.font = (Object.op_Implicit((Object)(object)HGTextMeshProUGUI.defaultLanguageFont) ? HGTextMeshProUGUI.defaultLanguageFont : (Object.op_Implicit((Object)(object)val2) ? val2.font : TMP_Settings.defaultFontAsset));
			MPEventSystem obj = source.eventSystem;
			int cursorOpenerCount = obj.cursorOpenerCount;
			obj.cursorOpenerCount = cursorOpenerCount + 1;
			MPEventSystem obj2 = source.eventSystem;
			cursorOpenerCount = obj2.cursorOpenerForGamepadCount;
			obj2.cursorOpenerForGamepadCount = cursorOpenerCount + 1;
			ArenaHostSettings.ClientView = null;
			try
			{
				instance.Create();
			}
			catch (Exception ex)
			{
				Plugin.Warn("Could not open match settings: " + ex);
				instance.Close();
			}
		}

		private void Create()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Expected O, but got Unknown
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: 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_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Expected O, but got Unknown
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Expected O, but got Unknown
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			panel = new GameObject("Match rules", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			panel.transform.SetParent(((Component)this).transform, false);
			RectTransform component = panel.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.07f, 0.07f);
			component.anchorMax = new Vector2(0.93f, 0.93f);
			Vector2 val = (component.offsetMin = (component.offsetMax = Vector2.zero));
			((Graphic)panel.GetComponent<Image>()).color = new Color(0.035f, 0.06f, 0.075f, 0.94f);
			ArenaStyle.Border(panel, new Color(0.65f, 0.95f, 0.6f), 2f);
			TMP_Text obj = Label(panel.transform, "Match settings", 34f);
			Place(obj.rectTransform, 24f, 16f, -24f, 48f);
			obj.fontStyle = (FontStyles)3;
			status = Label(panel.transform, host ? "Host · changes save directly to RiskOfOptions" : "Host settings · view only", 19f);
			Place(status.rectTransform, 24f, 72f, -24f, 27f);
			((Graphic)status).color = (host ? new Color(0.7f, 1f, 0.65f) : new Color(0.65f, 0.85f, 1f));
			Place(Label(panel.transform, host ? "These rules apply to the next new match. Scrapper changes are live; map settings apply in the lobby." : "Only the host can edit these rules. Values update when the host changes them.", 16f).rectTransform, 24f, 104f, -24f, 28f);
			GameObject val3 = new GameObject("Rule categories", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(panel.transform, false);
			categoryList = val3.GetComponent<RectTransform>();
			categoryList.anchorMin = new Vector2(0f, 0f);
			categoryList.anchorMax = new Vector2(0.2f, 1f);
			categoryList.offsetMin = new Vector2(22f, 90f);
			categoryList.offsetMax = new Vector2(-12f, -150f);
			GameObject val4 = new GameObject("Rules viewport", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(RectMask2D),
				typeof(ScrollRect)
			});
			val4.transform.SetParent(panel.transform, false);
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.21f, 0f);
			component2.anchorMax = Vector2.one;
			component2.offsetMin = new Vector2(0f, 90f);
			component2.offsetMax = new Vector2(-22f, -150f);
			((Graphic)val4.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.12f);
			GameObject val5 = new GameObject("Gameplay rules", new Type[3]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup),
				typeof(ContentSizeFitter)
			});
			val5.transform.SetParent((Transform)(object)component2, false);
			content = val5.GetComponent<RectTransform>();
			content.anchorMin = new Vector2(0f, 1f);
			content.anchorMax = Vector2.one;
			content.pivot = new Vector2(0.5f, 1f);
			val = (content.offsetMin = (content.offsetMax = Vector2.zero));
			VerticalLayoutGroup component3 = val5.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component3).spacing = 8f;
			((LayoutGroup)component3).padding = new RectOffset(3, 3, 3, 3);
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = childControlWidth;
			((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false;
			val5.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			scroll = val4.GetComponent<ScrollRect>();
			scroll.viewport = component2;
			scroll.content = content;
			scroll.horizontal = false;
			scroll.scrollSensitivity = 45f;
			scroll.movementType = (MovementType)2;
			back = Button(panel.transform, "Back", new UnityAction(Close));
			RectTransform component4 = ((Component)back).GetComponent<RectTransform>();
			((Vector2)(ref val))..ctor(0.5f, 0f);
			component4.anchorMax = val;
			component4.anchorMin = val;
			component4.pivot = new Vector2(0.5f, 0f);
			component4.anchoredPosition = new Vector2(0f, 22f);
			component4.sizeDelta = new Vector2(260f, 46f);
			if (host)
			{
				foreach (ConfigEntryBase matchEntry in Plugin.Settings.MatchEntries)
				{
					entries.Add(ArenaHostSettings.Id(matchEntry), matchEntry);
				}
				ApplyView(ArenaHostSettings.Capture());
			}
			else
			{
				status.text = "Host settings · view only · loading host values…";
			}
			if (Object.op_Implicit((Object)(object)eventSystem))
			{
				((EventSystem)eventSystem).SetSelectedGameObject((categoryButtons.Count > 0) ? ((Component)categoryButtons[0]).gameObject : ((Component)back).gameObject);
			}
		}

		private void Update()
		{
			if (!ArenaLobby.Selected || host != NetworkServer.active)
			{
				Close();
				return;
			}
			if (Input.GetKeyDown((KeyCode)27) && !ArenaStageSettings.IsOpen && ArenaStageSettings.LastClosedFrame != Time.frameCount)
			{
				Close();
				return;
			}
			try
			{
				if (host)
				{
					if (view == null || revision != Plugin.Settings.MatchRevision)
					{
						ApplyView(ArenaHostSettings.Capture());
					}
				}
				else
				{
					if (Time.unscaledTime >= nextRequest)
					{
						nextRequest = Time.unscaledTime + 0.75f;
						ArenaHostSettings.Request(((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)((NetworkUser u) => Object.op_Implicit((Object)(object)u) && u.localUser != null)));
					}
					if (ArenaHostSettings.ClientView != null && (view == null || revision != ArenaHostSettings.ClientView.Revision))
					{
						ApplyView(ArenaHostSettings.ClientView);
					}
				}
				if (Time.unscaledTime >= nextRefresh)
				{
					nextRefresh = Time.unscaledTime + 0.2f;
					foreach (Row value in rows.Values)
					{
						value.Refresh();
					}
				}
				KeepVisible();
			}
			catch (Exception ex)
			{
				Plugin.Warn("Match settings closed safely: " + ex);
				Close();
			}
		}

		private void ApplyView(HostSettingsView nex