Decompiled source of BonkSquad v0.2.13

BonkSquad.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.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Actors.Enemies;
using Assets.Scripts.Actors;
using Assets.Scripts.Actors.Enemies;
using Assets.Scripts.Actors.Player;
using Assets.Scripts.Camera;
using Assets.Scripts.Game.Combat;
using Assets.Scripts.Game.Combat.ConstantAttacks;
using Assets.Scripts.Game.Combat.EnemyDebuffs;
using Assets.Scripts.Game.Combat.EnemySpecialAttacks;
using Assets.Scripts.Game.MapGeneration.MapEvents;
using Assets.Scripts.Game.Other;
using Assets.Scripts.Game.Spawning;
using Assets.Scripts.Game.Spawning.New;
using Assets.Scripts.Inventory__Items__Pickups;
using Assets.Scripts.Inventory__Items__Pickups.AbilitiesPassive.Implementations;
using Assets.Scripts.Inventory__Items__Pickups.Chests;
using Assets.Scripts.Inventory__Items__Pickups.Interactables;
using Assets.Scripts.Inventory__Items__Pickups.Items;
using Assets.Scripts.Inventory__Items__Pickups.Items.ItemImplementations;
using Assets.Scripts.Inventory__Items__Pickups.Pickups;
using Assets.Scripts.Inventory__Items__Pickups.Stats;
using Assets.Scripts.Inventory__Items__Pickups.Weapons;
using Assets.Scripts.Inventory__Items__Pickups.Weapons.Attacks;
using Assets.Scripts.Inventory__Items__Pickups.Weapons.Projectiles;
using Assets.Scripts.Inventory__Items__Pickups.Weapons.WeaponPassives;
using Assets.Scripts.Managers;
using Assets.Scripts.Menu.Shop;
using Assets.Scripts.Objects.Particles___Effects.ParticleOpacity;
using Assets.Scripts.Objects.Pooling;
using Assets.Scripts.Saves___Serialization.Progression.Achievements;
using Assets.Scripts.Saves___Serialization.Progression.Stats;
using Assets.Scripts.Saves___Serialization.Progression.Unlocks;
using Assets.Scripts.Saves___Serialization.SaveFiles;
using Assets.Scripts.Settings___Saves.SaveFiles;
using Assets.Scripts.Settings___Saves.SaveFiles.ConfigSaves;
using Assets.Scripts.Steam;
using Assets.Scripts.UI.HUD;
using Assets.Scripts.UI.InGame.Levelup;
using Assets.Scripts.UI.InGame.Rewards;
using Assets.Scripts.Utility;
using Assets.Scripts._Data.MapsAndStages;
using Assets.Scripts._Data.Tomes;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BonkSquad.Lobby;
using BonkSquad.Net;
using BonkSquad.Sync;
using BonkSquad.UI;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Utility;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BonkSquad")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d9a8d88cabab9ba7d8230851c570d2e0091d4876")]
[assembly: AssemblyProduct("BonkSquad")]
[assembly: AssemblyTitle("BonkSquad")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 BonkSquad
{
	[BepInPlugin("local.BonkSquad", "BonkSquad", "0.2.13")]
	[BepInIncompatibility("com.BWFTeam.BonkWithFriends")]
	[BepInProcess("Megabonk.exe")]
	public sealed class Plugin : BasePlugin
	{
		public const string Guid = "local.BonkSquad";

		public const string Version = "0.2.13";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<MonsterDifficulty> Difficulty;

		internal static ConfigEntry<bool> ScaleWithPlayers;

		internal static ConfigEntry<KeyCode> LobbyKey;

		internal static ConfigEntry<bool> TeammateAttacks;

		internal static ConfigEntry<float> DebugScreenshotEvery;

		internal static ConfigEntry<int> UdpPort;

		internal static ConfigEntry<string> UdpId;

		internal static ConfigEntry<string> UdpJoinAddress;

		internal static ConfigEntry<bool> SharedChests;

		internal static ConfigEntry<string> DebugProbe;

		internal static ConfigEntry<bool> DebugSecondInstance;

		internal static ConfigEntry<string> DebugAutoConnect;

		internal static ConfigEntry<int> DebugSlowGeneration;

		internal static ConfigEntry<bool> DebugQuietRun;

		internal static ConfigEntry<float> DebugPushProps;

		internal static ConfigEntry<bool> DebugAutoStartRun;

		internal static ConfigEntry<bool> DebugLayoutDump;

		internal static ConfigEntry<bool> DebugTrace;

		internal static ConfigEntry<float> DebugKillAfter;

		internal static ConfigEntry<float> DebugMenuAfterGameOver;

		internal static ConfigEntry<float> DebugNextStageAfter;

		internal static ConfigEntry<float> DebugBossAfter;

		internal static ConfigEntry<bool> DebugOpenLobby;

		internal static ConfigEntry<float> DebugStormAfter;

		internal static ConfigEntry<float> DebugChargeShrineAfter;

		internal static ConfigEntry<float> DebugChoiceStorm;

		internal static ConfigEntry<bool> DebugMenuStart;

		internal static ConfigEntry<float> DebugReadyAfter;

		internal static ConfigEntry<float> DebugChallengeKillAfter;

		internal static ConfigEntry<float> DebugChestPair;

		internal static ConfigEntry<float> DebugSwarmAfter;

		internal static ConfigEntry<float> DebugCharacterPickAfter;

		internal static ConfigEntry<bool> DebugDropFightLink;

		internal static ConfigEntry<string> DebugForgetQuests;

		internal static ConfigEntry<string> DebugChallenge;

		internal static ConfigEntry<int> DebugTier;

		internal static ConfigEntry<int> DebugLayoutSwap;

		internal static ConfigEntry<float> DebugFinalStageAfter;

		internal static ConfigEntry<bool> DebugGod;

		internal static ConfigEntry<float> DebugTeleportAwayAfter;

		internal static ConfigEntry<string> DebugMap;

		internal static ConfigEntry<string> DebugCharacter;

		internal static ConfigEntry<bool> DebugAutoRevive;

		internal static ConfigEntry<bool> DebugCommsTest;

		internal static ConfigEntry<string> DebugUseNearest;

		internal static ConfigEntry<float> DebugScreenshotAfter;

		internal static ConfigEntry<bool> DebugFillLoadout;

		internal static ConfigEntry<string> DebugWeapons;

		internal static ConfigEntry<string> DebugItems;

		internal static bool DebugOn;

		internal static ConfigEntry<int> DebugGroundSkew;

		internal static ConfigEntry<string> DebugSpawnPowerup;

		internal static ConfigEntry<string> DebugNetDrop;

		internal static ConfigEntry<bool> DebugSteamJoinSelfTest;

		internal static ConfigEntry<float> DebugFreezeAt;

		internal static ConfigEntry<KeyCode> ReviveKey;

		internal static ConfigEntry<int> DebugRngSkew;

		internal static ConfigEntry<int> DebugLayoutJitter;

		internal static ConfigEntry<float> DebugTombstoneAt;

		internal static ConfigEntry<float> DebugAutoConnectDelay;

		internal static ConfigEntry<float> DebugStageEndAfter;

		internal static ConfigEntry<float> DebugCryptAfter;

		internal static ConfigEntry<float> DebugFinalBossStep;

		internal static ConfigEntry<bool> DebugFinalHelpers;

		public override void Load()
		{
			//IL_08b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_08bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_08dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_08fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_090d: Unknown result type (might be due to invalid IL or missing references)
			//IL_091d: Unknown result type (might be due to invalid IL or missing references)
			//IL_092d: Unknown result type (might be due to invalid IL or missing references)
			//IL_093d: Unknown result type (might be due to invalid IL or missing references)
			//IL_094d: Unknown result type (might be due to invalid IL or missing references)
			//IL_095d: Unknown result type (might be due to invalid IL or missing references)
			//IL_096d: Unknown result type (might be due to invalid IL or missing references)
			//IL_097d: Unknown result type (might be due to invalid IL or missing references)
			//IL_098d: Unknown result type (might be due to invalid IL or missing references)
			//IL_099d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a46: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a4c: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			SharedChests = ((BasePlugin)this).Config.Bind<bool>("Gameplay", "SharedChests", false, "Host setting: chests that cost gold are shared - whoever opens one first uses it up for everyone, and it's gone from everyone's map. Off (the default): every player can open every chest once for themselves, so there are always enough.");
			Difficulty = ((BasePlugin)this).Config.Bind<MonsterDifficulty>("Gameplay", "Difficulty", MonsterDifficulty.Normal, "Host setting, also in the lobby: how tough the monsters are. Normal is the game's own strength.");
			ScaleWithPlayers = ((BasePlugin)this).Config.Bind<bool>("Gameplay", "ScaleWithPlayers", true, "Host setting, also in the lobby: every extra player adds 50% monster health and 30% more monsters.");
			LobbyKey = ((BasePlugin)this).Config.Bind<KeyCode>("General", "LobbyKey", (KeyCode)288, "Opens and closes the BonkSquad lobby window.");
			TeammateAttacks = ((BasePlugin)this).Config.Bind<bool>("General", "TeammateAttacks", true, "Shows your teammates' weapon effects. Turn it off on a slow PC; their attacks still do their damage.");
			DebugScreenshotEvery = ((BasePlugin)this).Config.Bind<float>("Debug", "ScreenshotEvery", 0f, "Testing aid: after ScreenshotAfter's first screenshot, another one every this many seconds, up to 8 per stage (0 = off).");
			ReviveKey = ((BasePlugin)this).Config.Bind<KeyCode>("General", "ReviveKey", (KeyCode)101, "At a teammate's grave: brings them back right away.");
			UdpPort = ((BasePlugin)this).Config.Bind<int>("Direct", "Port", 27555, "UDP port used when hosting a direct (LAN/test) session.");
			UdpId = ((BasePlugin)this).Config.Bind<string>("Direct", "Id", "", "Random id of this game copy in direct sessions, so a restarted game is recognised as the same player. Filled in on first use.");
			UdpJoinAddress = ((BasePlugin)this).Config.Bind<string>("Direct", "JoinAddress", "127.0.0.1", "Address (optionally host:port) for joining a direct session.");
			DebugSecondInstance = ((BasePlugin)this).Config.Bind<bool>("Debug", "SecondInstance", false, "Set on the second game copy when testing two instances on one PC: blocks saving and Steam stat uploads so it can't overwrite the real save.");
			DebugAutoConnect = ((BasePlugin)this).Config.Bind<string>("Debug", "AutoConnect", "", "Testing aid: 'host' starts a direct (UDP) host, 'join' joins JoinAddress, a few seconds after the main menu appears.");
			DebugAutoStartRun = ((BasePlugin)this).Config.Bind<bool>("Debug", "AutoStartRun", false, "Testing aid for the host: starts a run on the first map as soon as every client in the session is ready.");
			DebugLayoutDump = ((BasePlugin)this).Config.Bind<bool>("Debug", "LayoutDump", false, "Writes the positions of all interactables to BepInEx/bonksquad-layout.txt after each map generation, and every object's state and the game's counters to bonksquad-states-<stage>.txt 2 and 25 seconds into each stage (to compare peers).");
			DebugTrace = ((BasePlugin)this).Config.Bind<bool>("Debug", "Trace", false, "Logs own and remote player positions every 2 seconds during a run, and every choice window the game asks for and opens (with the caller).");
			DebugFinalHelpers = ((BasePlugin)this).Config.Bind<bool>("Debug", "FinalHelpers", false, "Testing aid: charges the first active pylon of the final fight, and the host walks through the final portal once it's there.");
			DebugFinalBossStep = ((BasePlugin)this).Config.Bind<float>("Debug", "FinalBossStep", 0f, "Testing aid for the host: takes a fifth of the final boss's health every this many seconds (0 = off).");
			DebugStageEndAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "StageEndAfter", 0f, "Testing aid for the host: jumps the stage timer to 10 seconds before its end this many seconds after the stage started (0 = off).");
			DebugSteamJoinSelfTest = ((BasePlugin)this).Config.Bind<bool>("Debug", "SteamJoinSelfTest", false, "Testing aid: checks at start that join requests from Steam would reach the mod, using Steam's stats callback.");
			DebugTombstoneAt = ((BasePlugin)this).Config.Bind<float>("Debug", "TombstoneAt", 0f, "Testing aid: puts a tombstone in front of the camera this many seconds into each stage, to look at it (0 = off).");
			DebugLayoutJitter = ((BasePlugin)this).Config.Bind<int>("Debug", "LayoutJitter", 0, "Testing aid for clients: moves this many objects after the map is generated (most a few meters, every tenth far away, every seventh removed), like another PC or save placing them differently. The host's layout must win.");
			DebugRngSkew = ((BasePlugin)this).Config.Bind<int>("Debug", "RngSkew", 0, "Testing aid: uses up this many random numbers at run start, like a different save does. Maps must still match.");
			DebugFreezeAt = ((BasePlugin)this).Config.Bind<float>("Debug", "FreezeAt", 0f, "Testing aid: freezes the game once for 8 seconds this many seconds after start, to check BonkSquad-hang.log. 0 = off.");
			DebugNetDrop = ((BasePlugin)this).Config.Bind<string>("Debug", "NetDrop", "", "Testing aid: 'start:seconds', e.g. '20:15' - drops all co-op traffic for that long, that many seconds into the first stage of each run, like a network outage.");
			DebugAutoConnectDelay = ((BasePlugin)this).Config.Bind<float>("Debug", "AutoConnectDelay", 8f, "Testing aid: seconds after the game started before AutoConnect hosts or joins (a long delay joins a run in progress).");
			DebugSpawnPowerup = ((BasePlugin)this).Config.Bind<string>("Debug", "SpawnPowerup", "", "Testing aid: 'Kind:seconds', e.g. 'Shield:10' - drops that power-up at your feet that many seconds into each stage.");
			DebugFillLoadout = ((BasePlugin)this).Config.Bind<bool>("Debug", "FillLoadout", false, "Testing aid: adds two weapons and three tomes at the start of each stage.");
			DebugPushProps = ((BasePlugin)this).Config.Bind<float>("Debug", "PushProps", 0f, "Testing aid: knocks over the nearest crates and pillars this many seconds into each stage (0 = off).");
			DebugQuietRun = ((BasePlugin)this).Config.Bind<bool>("Debug", "QuietRun", false, "Testing aid: stops all other testing aids once a run started, so that it runs like a normal game.");
			DebugSlowGeneration = ((BasePlugin)this).Config.Bind<int>("Debug", "SlowGeneration", 0, "Testing aid: waits this many milliseconds in every step of the map generator, like a slow PC.");
			DebugGroundSkew = ((BasePlugin)this).Config.Bind<int>("Debug", "GroundSkew", 0, "Testing aid for clients: removes, moves and adds this many trees, rocks or bushes before comparing them with the host's.");
			DebugItems = ((BasePlugin)this).Config.Bind<string>("Debug", "Items", "", "Testing aid: adds these items (comma-separated EItem names) at the start of each stage.");
			DebugWeapons = ((BasePlugin)this).Config.Bind<string>("Debug", "Weapons", "", "Testing aid: adds these weapons (comma-separated EWeapon names, or 'all') at the start of each stage.");
			DebugScreenshotAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "ScreenshotAfter", 0f, "Testing aid: saves a screenshot (BepInEx/bonksquad-shot-N.png) that many seconds into each stage, 0 = off.");
			DebugUseNearest = ((BasePlugin)this).Config.Bind<string>("Debug", "UseNearest", "", "Testing aid: 'Type:seconds', e.g. 'InteractableCoffin:12' - teleports to the nearest interactable of that type that many seconds into the stage and uses it.");
			DebugCommsTest = ((BasePlugin)this).Config.Bind<bool>("Debug", "CommsTest", false, "Testing aid: says hello in the chat and pings the crosshair 8 seconds into each stage.");
			DebugAutoRevive = ((BasePlugin)this).Config.Bind<bool>("Debug", "AutoRevive", false, "Testing aid: walks to a teammate's grave three seconds after they died.");
			DebugCharacter = ((BasePlugin)this).Config.Bind<string>("Debug", "Character", "", "Testing aid: selects this character (e.g. Fox) in the main menu, as if picked in the character menu.");
			DebugMap = ((BasePlugin)this).Config.Bind<string>("Debug", "Map", "", "Testing aid: map for AutoStartRun by name (e.g. Graveyard); empty = the first map.");
			DebugCryptAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "CryptAfter", 0f, "Testing aid: leaves the crypt this many seconds after the stage started (0 = off).");
			DebugTeleportAwayAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "TeleportAwayAfter", 0f, "Testing aid: teleports the local player to a random spot on the map this many seconds after the stage started (0 = off).");
			DebugGod = ((BasePlugin)this).Config.Bind<bool>("Debug", "God", false, "Testing aid: keeps the local player at full health.");
			DebugFinalStageAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "FinalStageAfter", 0f, "Testing aid for the host: jumps to the final boss stage this many seconds after the first stage started (0 = off).");
			DebugLayoutSwap = ((BasePlugin)this).Config.Bind<int>("Debug", "LayoutSwap", 0, "Testing aid for clients: turns this many chests, shrines or statues into another kind after the map is built, to test the layout alignment.");
			DebugMenuStart = ((BasePlugin)this).Config.Bind<bool>("Debug", "MenuStart", false, "Testing aid for the host: once a teammate is in the lobby, opens the game's map selection and presses its start, as a player would (instead of AutoStartRun's direct start).");
			DebugReadyAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "ReadyAfter", 0f, "Testing aid for clients with AutoConnect=join: presses Ready this many seconds after reaching the main menu (0 = right away).");
			DebugChallengeKillAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "ChallengeKillAfter", 0f, "Testing aid for the host: kills a challenge shrine's enemies this many seconds after it started (0 = off).");
			DebugTier = ((BasePlugin)this).Config.Bind<int>("Debug", "Tier", 0, "Testing aid: tier for AutoStartRun, counted from 0.");
			DebugChallenge = ((BasePlugin)this).Config.Bind<string>("Debug", "Challenge", "", "Testing aid: challenge for AutoStartRun by its internal name.");
			DebugForgetQuests = ((BasePlugin)this).Config.Bind<string>("Debug", "ForgetQuests", "", "Testing aid, second instances only (they never save): comma-separated quests this peer pretends it hasn't done.");
			DebugDropFightLink = ((BasePlugin)this).Config.Bind<bool>("Debug", "DropFightLink", false, "Testing aid for clients: ignores which enemies belong to the host's challenge shrines, coffins and graves, like a link that came too late.");
			DebugSwarmAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "SwarmAfter", 0f, "Testing aid for the host: starts the stage's next swarm from its timeline this many seconds into a stage (0 = off).");
			DebugCharacterPickAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "CharacterPickAfter", 0f, "Testing aid: this many seconds after reaching the main menu with a teammate, opens the lobby's character selection, confirms a character and logs which menu is open afterwards (0 = off).");
			DebugProbe = ((BasePlugin)this).Config.Bind<string>("Debug", "Probe", "", "Testing aid: comma-separated checks that log what they see - lobby (clicks through the lobby window and reports cut or overlapping texts), map (opens the map both ways and logs whether the squad cards step aside), scaling (the monster stats, enemies and their health), scalingleave (with scaling: the host closes the lobby 40 s into the run), portal (a client walks into the open boss portal and presses interact there), fog (the full map's fog around teammates and their map icons), listeners (who hears interactions), endscreen (opens the game's stats page after the run table and writes its layout), egg (the host strikes down the egg's frogs), weapons (what every weapon is made of, and how its first shots behave), attacks (teammates' weapon copies by type), attacksizes (compares effect sizes, shooter and copies), effects (everything that draws effects), fight (character fights; the host strikes the enemy down after 8 seconds), chainlightning (shoots a chain of lightning now and then).");
			DebugChestPair = ((BasePlugin)this).Config.Bind<float>("Debug", "ChestPair", 0f, "Testing aid: this many seconds into a stage, opens the two nearest chests at the same moment (with gold for both) and counts the chest windows (0 = off).");
			DebugChoiceStorm = ((BasePlugin)this).Config.Bind<float>("Debug", "ChoiceStorm", 0f, "Testing aid: this many seconds into a stage, triggers a level-up, a Moai and a charge shrine at once, then picks the first offer of every choice window and counts them (0 = off).");
			DebugChargeShrineAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "ChargeShrineAfter", 0f, "Testing aid: completes the nearest charge shrine this many seconds after the stage started (0 = off).");
			DebugStormAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "StormAfter", 0f, "Testing aid for the host on the desert: starts a sandstorm this many seconds after the stage started (0 = off).");
			DebugOpenLobby = ((BasePlugin)this).Config.Bind<bool>("Debug", "OpenLobby", false, "Testing aid: clicks the co-op button whenever the main menu loads.");
			DebugBossAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "BossAfter", 0f, "Testing aid: uses the stage's boss spawner this many seconds after the stage started (0 = off).");
			DebugNextStageAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "NextStageAfter", 0f, "Testing aid for the host: loads the next stage this many seconds after each stage started (0 = off).");
			DebugMenuAfterGameOver = ((BasePlugin)this).Config.Bind<float>("Debug", "MenuAfterGameOver", 0f, "Testing aid: leaves the death screen for the main menu this many seconds after a co-op game over (0 = off).");
			DebugKillAfter = ((BasePlugin)this).Config.Bind<float>("Debug", "KillAfter", 0f, "Testing aid: kills your own player this many seconds into a co-op run (0 = off).");
			DebugOn = ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)((BasePlugin)this).Config).Any((KeyValuePair<ConfigDefinition, ConfigEntryBase> e) => e.Key.Section == "Debug" && e.Key.Key != "SecondInstance" && !object.Equals(e.Value.BoxedValue, e.Value.DefaultValue));
			Harmony val = new Harmony("local.BonkSquad");
			val.PatchAll(typeof(SecondInstanceGuard));
			val.PatchAll(typeof(RunSync));
			val.PatchAll(typeof(EnemySync));
			val.PatchAll(typeof(DeathSync));
			val.PatchAll(typeof(WorldSync));
			val.PatchAll(typeof(ChargeShrineSync));
			val.PatchAll(typeof(ChoiceGuard));
			val.PatchAll(typeof(MapEventSync));
			val.PatchAll(typeof(FinalFightSync));
			val.PatchAll(typeof(CryptSync));
			val.PatchAll(typeof(MenuLobby));
			val.PatchAll(typeof(Comms));
			val.PatchAll(typeof(LeaderboardGuard));
			val.PatchAll(typeof(FightLinkSync));
			val.PatchAll(typeof(AttackSync));
			val.PatchAll(typeof(QuestSync));
			LobbyManager.Init();
			RunSync.Init();
			PlayerSync.Init();
			EnemySync.Init();
			DeathSync.Init();
			WorldSync.Init();
			LayoutSync.Init();
			ChoiceGuard.Init();
			MapEventSync.Init();
			FinalFightSync.Init();
			CryptSync.Init();
			GroundSync.Init();
			ReviveSync.Init();
			Comms.Init();
			SummarySync.Init();
			FightLinkSync.Init();
			LoadoutSync.Init();
			PowerupSync.Init();
			AttackSync.Init();
			QuestSync.Init();
			ClockSync.Init();
			PropSync.Init();
			MonsterScaling.Init();
			((BasePlugin)this).AddComponent<Runner>();
			Watchdog.Start();
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(17, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("BonkSquad ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("0.2.13");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(DebugSecondInstance.Value ? " (second instance: saving disabled)" : string.Empty);
			}
			log.LogInfo(val2);
		}
	}
	public sealed class Runner : MonoBehaviour
	{
		private static readonly Dictionary<string, float> LastError = new Dictionary<string, float>();

		private static bool _froze;

		public Runner(IntPtr ptr)
			: base(ptr)
		{
		}

		private static void Step(Action step, string name)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			Watchdog.Enter(name);
			try
			{
				step();
			}
			catch (Exception ex)
			{
				if (!LastError.TryGetValue(name, out var value) || Time.unscaledTime - value > 1f)
				{
					LastError[name] = Time.unscaledTime;
					ManualLogSource logger = Plugin.Logger;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(11, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Runner] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					logger.LogError(val);
				}
			}
			finally
			{
				Watchdog.Leave();
			}
		}

		public void Update()
		{
			Watchdog.Frame();
			if (Plugin.DebugFreezeAt.Value > 0f && Time.unscaledTime > Plugin.DebugFreezeAt.Value && !_froze)
			{
				_froze = true;
				Thread.Sleep(8000);
			}
			Step(LobbyManager.Update, "LobbyManager.Update");
			Step(Session.Update, "Session.Update");
			Step(RunSync.Update, "RunSync.Update");
			Step(LayoutSync.Update, "LayoutSync.Update");
			Step(PlayerSync.Update, "PlayerSync.Update");
			Step(EnemySync.Update, "EnemySync.Update");
			Step(PauseSync.Update, "PauseSync.Update");
			Step(ChoiceGuard.Update, "ChoiceGuard.Update");
			Step(DeathSync.Update, "DeathSync.Update");
			Step(Regroup.Update, "Regroup.Update");
			Step(WorldSync.Update, "WorldSync.Update");
			Step(MapEventSync.Update, "MapEventSync.Update");
			Step(FinalFightSync.Update, "FinalFightSync.Update");
			Step(CryptSync.Update, "CryptSync.Update");
			Step(ReviveSync.Update, "ReviveSync.Update");
			Step(Comms.Update, "UI.Comms.Update");
			Step(SummarySync.Update, "SummarySync.Update");
			Step(FightLinkSync.Update, "FightLinkSync.Update");
			Step(LoadoutSync.Update, "LoadoutSync.Update");
			Step(SteamJoinRequests.Update, "SteamJoinRequests.Update");
			Step(PowerupSync.Update, "PowerupSync.Update");
			Step(AttackSync.Update, "AttackSync.Update");
			Step(QuestSync.Update, "QuestSync.Update");
			Step(ClockSync.Update, "ClockSync.Update");
			Step(PropSync.Update, "PropSync.Update");
			Step(MonsterScaling.Update, "MonsterScaling.Update");
			Step(SquadHud.Update, "UI.SquadHud.Update");
			if (Plugin.DebugOn && (!Plugin.DebugQuietRun.Value || !RunSync.InRun))
			{
				Step(DebugTools.Update, "DebugTools.Update");
			}
			Step(LobbyWindow.Update, "LobbyWindow.Update");
			Step(MenuLobby.Update, "UI.MenuLobby.Update");
		}

		public void LateUpdate()
		{
			Step(SquadHud.LateUpdate, "UI.SquadHud.LateUpdate");
		}

		public void OnGUI()
		{
			Step(PlayerSync.DrawNameplates, "PlayerSync.DrawNameplates (OnGUI)");
			Step(ReviveSync.Draw, "ReviveSync.Draw (OnGUI)");
			Step(PartyPanel.Draw, "UI.PartyPanel.Draw (OnGUI)");
			Step(Comms.Draw, "UI.Comms.Draw (OnGUI)");
			Step(SummarySync.Draw, "SummarySync.Draw (OnGUI)");
			Step(LobbyWindow.Draw, "LobbyWindow.Draw (OnGUI)");
			Step(LayoutSync.DrawWaiting, "LayoutSync.DrawWaiting (OnGUI)");
			Step(Toasts.Draw, "Toasts.Draw (OnGUI)");
		}

		public void OnApplicationQuit()
		{
			ChoiceGuard.RestoreSettings();
			LobbyManager.Leave();
		}
	}
	[HarmonyPatch]
	internal static class SecondInstanceGuard
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(SaveManager), "SaveConfig")]
		[HarmonyPatch(typeof(SaveManager), "SaveControllers")]
		[HarmonyPatch(typeof(SaveManager), "SaveProgression")]
		[HarmonyPatch(typeof(SaveManager), "SaveStats")]
		[HarmonyPatch(typeof(SaveManager), "SaveTemp")]
		[HarmonyPatch(typeof(SteamStatsManager), "TryUploadStats")]
		[HarmonyPatch(typeof(SteamAchievementsManager), "TryUploadAchievements")]
		private static bool Block()
		{
			return !Plugin.DebugSecondInstance.Value;
		}
	}
	internal static class Watchdog
	{
		private const double StuckAfter = 5.0;

		private static volatile string _step = "start";

		private static long _stepSince = DateTime.UtcNow.Ticks;

		private static volatile bool _inStep;

		private static long _lastFrame = DateTime.UtcNow.Ticks;

		private static string _path;

		private static Thread _thread;

		private static bool _captured;

		internal static void Start()
		{
			_path = Path.Combine(Paths.BepInExRootPath, "BonkSquad-hang.log");
			_thread = new Thread(Watch)
			{
				IsBackground = true,
				Name = "BonkSquad watchdog"
			};
			_thread.Start();
		}

		internal static void Frame()
		{
			if (!_captured)
			{
				_captured = true;
			}
			Interlocked.Exchange(ref _lastFrame, DateTime.UtcNow.Ticks);
		}

		internal static void Enter(string step)
		{
			_step = step;
			Interlocked.Exchange(ref _stepSince, DateTime.UtcNow.Ticks);
			_inStep = true;
		}

		internal static void Leave()
		{
			_inStep = false;
		}

		private static void Watch()
		{
			bool flag = false;
			while (true)
			{
				Thread.Sleep(1000);
				long ticks = DateTime.UtcNow.Ticks;
				double totalSeconds = TimeSpan.FromTicks(ticks - Interlocked.Read(in _lastFrame)).TotalSeconds;
				if (totalSeconds < 5.0)
				{
					if (flag)
					{
						Write($"main thread runs again after {totalSeconds:0.0} s");
					}
					flag = false;
				}
				else if (!flag || !(totalSeconds % 30.0 >= 1.0))
				{
					flag = true;
					string value = (_inStep ? $"inside {_step} for {TimeSpan.FromTicks(ticks - Interlocked.Read(in _stepSince)).TotalSeconds:0.0} s" : ("outside the mod's update steps (last one: " + _step + ") - in the game, Steam or a patch"));
					Write($"main thread has not finished a frame for {totalSeconds:0.0} s, {value}");
				}
			}
		}

		private static void Write(string line)
		{
			try
			{
				File.AppendAllText(_path, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {line}{Environment.NewLine}");
			}
			catch
			{
			}
		}
	}
}
namespace BonkSquad.UI
{
	[HarmonyPatch]
	internal static class Comms
	{
		private sealed class Line
		{
			internal string Text;

			internal float At;
		}

		private sealed class Ping
		{
			internal ulong From;

			internal Vector3 Position;

			internal float At;
		}

		private const int MaxLines = 6;

		private const float LineTime = 12f;

		private const float PingTime = 6f;

		private const int MaxLength = 120;

		private static readonly List<Line> Lines = new List<Line>();

		private static readonly List<Ping> Pings = new List<Ping>();

		private static bool _typing;

		private static bool _focus;

		private static string _draft = string.Empty;

		private static float _nextPing;

		private static int _openedFrame;

		private static GUIStyle _lineStyle;

		internal static bool Typing => _typing;

		internal static void Init()
		{
			Session.On(MsgId.Chat, OnChat);
			Session.On(MsgId.WorldPing, OnPing);
			Session.Ended += delegate
			{
				_typing = false;
				Pings.Clear();
			};
			RunSync.MapReady += Pings.Clear;
		}

		private static string NameOf(ulong id)
		{
			if (!Session.Players.TryGetValue(id, out var value))
			{
				return "?";
			}
			return value.Name;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerInput), "IsConsoleOpen")]
		private static void AfterIsConsoleOpen(ref bool __result)
		{
			__result |= _typing;
		}

		internal static void Update()
		{
			if (Session.Active)
			{
				if (!_typing && Input.GetKeyDown((KeyCode)13))
				{
					_openedFrame = Time.frameCount;
					_typing = true;
					_focus = true;
					_draft = string.Empty;
				}
				if (!_typing && RunSync.InRun && !DeathSync.LocalDead && Input.GetMouseButtonDown(2) && Time.unscaledTime >= _nextPing)
				{
					_nextPing = Time.unscaledTime + 0.5f;
					PingCrosshair();
				}
			}
		}

		internal static void Say(string text)
		{
			text = ((text.Length > 120) ? text.Substring(0, 120) : text);
			Send(MsgId.Chat, delegate(NetWriter w)
			{
				w.String(text);
			}, 0uL, 0uL);
			AddLine(Session.LocalId, text);
		}

		internal static void PingCrosshair()
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0070: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return;
			}
			Ray val = main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
			Vector3 val2 = (((Object)(object)MyPlayer.Instance != (Object)null) ? ((Component)MyPlayer.Instance).transform.position : ((Ray)(ref val)).origin);
			float num = Vector3.Distance(((Ray)(ref val)).origin, val2) + 1.5f;
			RaycastHit hit = default(RaycastHit);
			if (Physics.Raycast(((Ray)(ref val)).GetPoint(num), ((Ray)(ref val)).direction, ref hit, 300f, -1, (QueryTriggerInteraction)1))
			{
				Send(MsgId.WorldPing, delegate(NetWriter w)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					w.Vector3(((RaycastHit)(ref hit)).point);
				}, 0uL, 0uL);
				AddPing(Session.LocalId, ((RaycastHit)(ref hit)).point);
			}
		}

		private static void Send(MsgId id, Action<NetWriter> body, ulong from = 0uL, ulong except = 0uL)
		{
			NetWriter netWriter = Session.Begin(id);
			netWriter.ULong((from == 0L) ? Session.LocalId : from);
			body(netWriter);
			if (Session.IsHost)
			{
				Session.Broadcast(reliable: true, except);
			}
			else
			{
				Session.Send(Session.HostId, reliable: true);
			}
		}

		private static void OnChat(ulong sender, NetReader r)
		{
			ulong num = r.ULong();
			string text = r.String();
			if (text.Length > 120)
			{
				text = text.Substring(0, 120);
			}
			if (Session.IsHost)
			{
				Send(MsgId.Chat, delegate(NetWriter w)
				{
					w.String(text);
				}, num, sender);
			}
			AddLine(num, text);
		}

		private static void OnPing(ulong sender, NetReader r)
		{
			//IL_000f: 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)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			ulong num = r.ULong();
			Vector3 pos = r.Vector3();
			if (Session.IsHost)
			{
				Send(MsgId.WorldPing, delegate(NetWriter w)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					w.Vector3(pos);
				}, num, sender);
			}
			if (RunSync.InRun)
			{
				AddPing(num, pos);
			}
		}

		private static void AddLine(ulong from, string text)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			string text2 = text.Replace("<", "‹").Replace(">", "›");
			Lines.Add(new Line
			{
				Text = "<b><color=#9AD8FF>" + NameOf(from) + "</color></b>: " + text2,
				At = Time.unscaledTime
			});
			while (Lines.Count > 6)
			{
				Lines.RemoveAt(0);
			}
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Comms] ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(NameOf(from));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
			}
			logger.LogInfo(val);
		}

		private static void AddPing(ulong from, Vector3 pos)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			Pings.RemoveAll((Ping p) => p.From == from);
			Pings.Add(new Ping
			{
				From = from,
				Position = pos,
				At = Time.unscaledTime
			});
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Comms] ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(NameOf(from));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pinged ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Vector3)(ref pos)).ToString("F0"));
			}
			logger.LogInfo(val);
		}

		internal static void Draw()
		{
			if (Session.Active)
			{
				DrawPings();
				DrawChat();
			}
		}

		private static void DrawPings()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			Pings.RemoveAll((Ping p) => Time.unscaledTime - p.At > 6f);
			Camera main = Camera.main;
			if (Pings.Count == 0 || (Object)(object)main == (Object)null || (int)Event.current.type != 7)
			{
				return;
			}
			Vector3 val = (((Object)(object)MyPlayer.Instance != (Object)null) ? ((Component)MyPlayer.Instance).transform.position : ((Component)main).transform.position);
			foreach (Ping ping in Pings)
			{
				float num = Time.unscaledTime - ping.At;
				float num2 = ((num < 1f) ? ((Mathf.Repeat(num * 4f, 1f) < 0.6f) ? 1f : 0.4f) : Mathf.Clamp01((6f - num) / 1.5f));
				string text = $"◆ {NameOf(ping.From)} ({Vector3.Distance(val, ping.Position):0} m)";
				WorldLabel.Draw(main, ping.Position + Vector3.up * 0.5f, text, new Color(1f, 0.85f, 0.35f, num2));
			}
		}

		private static void DrawChat()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Invalid comparison between Unknown and I4
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Invalid comparison between Unknown and I4
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Invalid comparison between Unknown and I4
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Invalid comparison between Unknown and I4
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Invalid comparison between Unknown and I4
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: 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: Invalid comparison between Unknown and I4
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Invalid comparison between Unknown and I4
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Invalid comparison between Unknown and I4
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerSync.MapOpen && !_typing)
			{
				return;
			}
			if (_lineStyle == null)
			{
				_lineStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15,
					richText = true,
					wordWrap = true
				};
			}
			float num = 14f;
			float num2 = (float)Screen.height * 0.62f;
			float num3 = 420f;
			if ((int)Event.current.type == 7)
			{
				Color color = GUI.color;
				foreach (Line line in Lines)
				{
					float num4 = Time.unscaledTime - line.At;
					if (_typing || !(num4 > 12f))
					{
						GUI.color = new Color(1f, 1f, 1f, _typing ? 1f : Mathf.Clamp01((12f - num4) / 2f));
						GUI.Label(new Rect(num + 1f, num2 + 1f, num3, 22f), "<color=black>" + StripColors(line.Text) + "</color>", _lineStyle);
						GUI.Label(new Rect(num, num2, num3, 22f), line.Text, _lineStyle);
						num2 += 22f;
					}
				}
				GUI.color = color;
			}
			else
			{
				num2 += 22f * (float)Lines.Count;
			}
			if (!_typing)
			{
				return;
			}
			Event current2 = Event.current;
			if (Time.frameCount == _openedFrame && (int)current2.type == 4 && ((int)current2.keyCode == 13 || (int)current2.keyCode == 271))
			{
				current2.Use();
			}
			else if ((int)current2.type == 4 && ((int)current2.keyCode == 13 || (int)current2.keyCode == 271))
			{
				string text = _draft.Trim();
				if (text.Length > 0)
				{
					Say(text);
				}
				_typing = false;
				current2.Use();
				return;
			}
			if ((int)current2.type == 4 && (int)current2.keyCode == 27)
			{
				_typing = false;
				current2.Use();
				return;
			}
			int keyboardControl = GUIUtility.GetControlID((FocusType)2) + 1;
			_draft = GUI.TextField(new Rect(num, num2 + 4f, num3, 26f), _draft, 120);
			if (_focus)
			{
				GUIUtility.keyboardControl = keyboardControl;
				_focus = false;
			}
		}

		private static string StripColors(string text)
		{
			return Regex.Replace(text, "</?color[^>]*>", string.Empty);
		}
	}
	internal static class LobbyWindow
	{
		private const float Width = 400f;

		private const float Row = 30f;

		private const float Pad = 12f;

		private static bool _open;

		private static bool _showDebug;

		private static string _udpAddress;

		private static GUIStyle _title;

		private static GUIStyle _label;

		private static GUIStyle _small;

		private static GUIStyle _button;

		private static float _y;

		private static Rect _panel;

		private static float _lastHeight = 200f;

		internal static bool Open => _open;

		internal static void Close()
		{
			_open = false;
			MenuLobby.Close();
		}

		internal static void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(Plugin.LobbyKey.Value))
			{
				_open = !_open;
			}
			if (_open)
			{
				LobbyManager.RefreshFriendLobbies();
			}
		}

		internal static void Draw()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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)
			EnsureStyles();
			if (!_open)
			{
				if (IsMainMenu() && !MenuLobby.Available && GUI.Button(new Rect(16f, 16f, 140f, 36f), Session.Active ? "BonkSquad ●" : "BonkSquad", _button))
				{
					_open = true;
				}
				return;
			}
			if (_udpAddress == null)
			{
				_udpAddress = Plugin.UdpJoinAddress.Value;
			}
			_panel = new Rect(16f, 16f, 400f, PanelHeight());
			GUI.Box(_panel, string.Empty);
			GUI.Box(_panel, string.Empty);
			_y = ((Rect)(ref _panel)).y + 12f;
			Label("BonkSquad 0.2.13", _title);
			if (CloseButton())
			{
				_open = false;
			}
			switch (LobbyManager.Current)
			{
			case LobbyManager.State.Idle:
				DrawIdle();
				break;
			case LobbyManager.State.Creating:
			case LobbyManager.State.Joining:
				Label(LobbyManager.Status, _label);
				if (Button("Cancel"))
				{
					LobbyManager.Leave();
				}
				break;
			case LobbyManager.State.InSession:
				DrawSession();
				break;
			}
			if (LobbyManager.Current != LobbyManager.State.InSession && LobbyManager.Status.Length > 0)
			{
				Label(LobbyManager.Status, _small);
			}
			_lastHeight = _y - ((Rect)(ref _panel)).y + 12f;
		}

		private static float PanelHeight()
		{
			return _lastHeight;
		}

		private static void DrawIdle()
		{
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			if (Button("Create Steam lobby"))
			{
				LobbyManager.HostSteam();
			}
			Label("Friends in BonkSquad:", _label);
			if (LobbyManager.FriendLobbies.Count == 0)
			{
				Label("  (no open lobby found)", _small);
			}
			foreach (LobbyManager.FriendLobby item in LobbyManager.FriendLobbies.ToList())
			{
				bool flag = item.Version == LobbyManager.LobbyVersion;
				string text = (flag ? ("Join: " + item.Name) : (item.Name + " (" + ((item.Version.Length == 0) ? "not a BonkSquad lobby" : ("Version " + item.Version)) + ")"));
				GUI.enabled = flag;
				if (Button(text))
				{
					LobbyManager.JoinSteam(item.Lobby);
				}
				GUI.enabled = true;
			}
			Space();
			if (Button(_showDebug ? "▾ Direct connection (UDP/LAN)" : "▸ Direct connection (UDP/LAN)"))
			{
				_showDebug = !_showDebug;
			}
			if (_showDebug)
			{
				if (Button($"UDP host on port {Plugin.UdpPort.Value}"))
				{
					LobbyManager.HostUdp();
				}
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((Rect)(ref _panel)).x + 12f, _y, 266f, 26f);
				_udpAddress = GUI.TextField(val, _udpAddress ?? string.Empty);
				if (GUI.Button(new Rect(((Rect)(ref val)).xMax + 6f, _y, 104f, 26f), "Connect", _button))
				{
					Plugin.UdpJoinAddress.Value = _udpAddress;
					LobbyManager.JoinUdp(_udpAddress);
				}
				_y += 30f;
			}
		}

		private static void DrawSession()
		{
			string text = Session.Transport?.Name ?? "?";
			Label(Session.IsHost ? ("Host (" + text + ")") : (Session.Connected ? ("Connected (" + text + ")") : LobbyManager.Status), _label);
			Space();
			foreach (Player item in Session.Players.Values.OrderBy((Player p) => p.Slot))
			{
				string value = ((item.Id == Session.LocalId) ? "you" : ((item.RttMs < 0f) ? "…" : $"{item.RttMs:0} ms"));
				string value2 = ((item.Id == Session.HostId) ? " ★" : string.Empty);
				Label($"{item.Slot + 1}. {item.Name}{value2}   {(item.Ready ? "ready" : "not ready")}   {value}", _label);
			}
			Space();
			if (LobbyManager.LobbyId != 0L && Button("Invite friends (Steam overlay)"))
			{
				LobbyManager.OpenInviteDialog();
			}
			if (Session.IsClient && Session.Connected)
			{
				bool flag = Session.Local?.Ready ?? false;
				if (Button(flag ? "Not ready" : "Ready"))
				{
					Session.SetReady(!flag);
				}
			}
			if (Session.IsHost)
			{
				Label("Start the run from the normal game menu – everyone else follows automatically.", _small);
			}
			else if (Session.Connected)
			{
				Label("Pick your character in the game menu; the host starts the run.", _small);
			}
			if (Button(Session.IsHost ? "Close lobby" : "Leave lobby"))
			{
				LobbyManager.Leave();
			}
		}

		internal static bool IsMainMenu()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string mainMenuSceneName = MapController.mainMenuSceneName;
				Scene activeScene = SceneManager.GetActiveScene();
				return ((Scene)(ref activeScene)).name == (string.IsNullOrEmpty(mainMenuSceneName) ? "MainMenu" : mainMenuSceneName);
			}
			catch
			{
				return false;
			}
		}

		private static void Label(string text, GUIStyle style)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect(((Rect)(ref _panel)).x + 12f, _y, 376f, 30f), text, style);
			_y += ((style == _small) ? 22f : 30f);
		}

		private static bool Button(string text)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			bool result = GUI.Button(new Rect(((Rect)(ref _panel)).x + 12f, _y, 376f, 26f), text, _button);
			_y += 30f;
			return result;
		}

		private static bool CloseButton()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return GUI.Button(new Rect(((Rect)(ref _panel)).xMax - 34f, ((Rect)(ref _panel)).y + 8f, 26f, 24f), "✕", _button);
		}

		private static void Space()
		{
			_y += 8f;
		}

		private static void EnsureStyles()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			if (_title == null)
			{
				_title = new GUIStyle(GUI.skin.label)
				{
					fontSize = 20,
					fontStyle = (FontStyle)1
				};
				_label = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15
				};
				_small = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					wordWrap = true
				};
				_small.normal.textColor = new Color(0.8f, 0.8f, 0.85f);
				_button = new GUIStyle(GUI.skin.button)
				{
					fontSize = 15
				};
			}
		}
	}
	[HarmonyPatch]
	internal static class MenuLobby
	{
		private const string MainPath = "UI/Tabs/Menu/Content/Main";

		private const float RefreshInterval = 0.25f;

		private const float WindowWidth = 520f;

		private const float HeaderHeight = 80f;

		private const float SidePadding = 22f;

		private const float EndPadding = 14f;

		private const float RowSpacing = 8f;

		private const float ContentWidth = 476f;

		private const float PlayerHeight = 48f;

		private const float ButtonHeight = 50f;

		private static readonly HashSet<string> Strip = new HashSet<string> { "LocalizeStringEvent", "ResizeOnLocalization", "TextSizer", "LinkButton", "LanguageButton", "AlertIcon", "ContentSizeFitter" };

		private static GameObject _menuButton;

		private static TextMeshProUGUI _menuButtonText;

		private static GameObject _window;

		private static RectTransform _windowRect;

		private static RectTransform _content;

		private static float _contentHeight;

		private static int _rows;

		private static readonly Dictionary<ulong, TextMeshProUGUI> Pings = new Dictionary<ulong, TextMeshProUGUI>();

		private static GameObject _leaderboards;

		private static GameObject _buttonTemplate;

		private static TMP_FontAsset _font;

		private static string _shown = string.Empty;

		private static float _nextRefresh;

		private static bool _open;

		private static bool _failed;

		private static float _clickAt = -1f;

		private static MapSelectionUi _pending;

		private static string _pendingMap = string.Empty;

		private static bool _starting;

		private static bool _wasInRun;

		private static bool _choosingMap;

		private static int _sentCharacter = -2;

		private static float _sentAt;

		private static readonly Color Dim = new Color(0.78f, 0.8f, 0.78f);

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

		internal static bool Available => !_failed;

		internal static bool IsOpen
		{
			get
			{
				if (_open && (Object)(object)_window != (Object)null)
				{
					return _window.activeInHierarchy;
				}
				return false;
			}
		}

		internal static bool PendingForTest => (Object)(object)_pending != (Object)null;

		internal static void Update()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			if (_wasInRun && !RunSync.InRun && Session.IsClient)
			{
				Player local = Session.Local;
				if (local != null && local.Ready)
				{
					Session.SetReady(ready: false);
				}
			}
			_wasInRun = RunSync.InRun;
			if (!LobbyWindow.IsMainMenu())
			{
				_open = false;
				_pending = null;
				return;
			}
			StartPending();
			if ((Object)(object)_menuButton == (Object)null)
			{
				Build();
			}
			if ((Object)(object)_menuButton == (Object)null)
			{
				return;
			}
			ShareCharacter();
			((TMP_Text)_menuButtonText).text = (Session.Active ? "Co-op <size=60%><color=#7CFC9A>●</color></size>" : "Co-op");
			if (_clickAt > 0f && Time.unscaledTime >= _clickAt)
			{
				_clickAt = -1f;
				EventSystem current = EventSystem.current;
				ExecuteEvents.Execute<IPointerClickHandler>(_menuButton, (BaseEventData)new PointerEventData(current), ExecuteEvents.pointerClickHandler);
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(80, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[MenuLobby] debug click on the menu button: window open ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_open);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", main tab still active ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_menuButton.activeInHierarchy);
				}
				logger.LogInfo(val);
			}
			if ((Object)(object)_window != (Object)null && _window.activeSelf != _open)
			{
				_window.SetActive(_open);
				if ((Object)(object)_leaderboards != (Object)null)
				{
					_leaderboards.SetActive(!_open);
				}
				_shown = string.Empty;
			}
			if (_open && Time.unscaledTime >= _nextRefresh)
			{
				_nextRefresh = Time.unscaledTime + 0.25f;
				LobbyManager.RefreshFriendLobbies();
				Refresh();
			}
		}

		private static List<Player> NotReady()
		{
			return (from p in Session.Players.Values
				where p.Id != Session.LocalId && !p.Away && !p.Ready
				orderby p.Slot
				select p).ToList();
		}

		internal static bool StartWhenReady(MapSelectionUi ui)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			if (!Session.IsHost || _starting || NotReady().Count == 0)
			{
				_pending = null;
				return true;
			}
			_pending = ui;
			RunConfig runConfig = ui.runConfig;
			_pendingMap = (((Object)(object)((runConfig != null) ? runConfig.mapData : null) != (Object)null) ? $"{runConfig.mapData.eMap}, tier {runConfig.mapTierIndex + 1}" : "the map");
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[MenuLobby] ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_pendingMap);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" chosen, waiting for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", from p in NotReady()
					select p.Name));
			}
			logger.LogInfo(val);
			Toasts.Show(_pendingMap + " chosen – the run starts once everyone is ready", new Color(0.6f, 0.9f, 1f));
			MainMenu obj = Object.FindObjectOfType<MainMenu>();
			if (obj != null)
			{
				obj.GoToMenu();
			}
			_open = true;
			_shown = string.Empty;
			return false;
		}

		private static void StartPending()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if ((Object)(object)_pending == (Object)null)
			{
				return;
			}
			if (!Session.IsHost || (Object)(object)_pending == (Object)null || RunSync.InRun)
			{
				_pending = null;
			}
			else if (NotReady().Count <= 0)
			{
				MapSelectionUi pending = _pending;
				_pending = null;
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[MenuLobby] everyone is ready, starting ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_pendingMap);
				}
				logger.LogInfo(val);
				_starting = true;
				try
				{
					pending.StartMap();
				}
				finally
				{
					_starting = false;
				}
			}
		}

		private static void ChooseMap()
		{
			MainMenu val = Object.FindObjectOfType<MainMenu>();
			if (!((Object)(object)val == (Object)null))
			{
				_open = false;
				OpenMapSelection(val);
			}
		}

		internal static void OpenMapSelection(MainMenu menu)
		{
			_choosingMap = true;
			try
			{
				menu.GoToMapSelection();
			}
			finally
			{
				_choosingMap = false;
			}
		}

		private static void CancelStart()
		{
			_pending = null;
			_shown = string.Empty;
		}

		private static void ShareCharacter()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected I4, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!Session.Active || Session.Local == null)
			{
				_sentCharacter = -2;
				return;
			}
			if (Plugin.DebugCharacter.Value.Length > 0 && _sentCharacter == -2 && Enum.TryParse<ECharacter>(Plugin.DebugCharacter.Value, ignoreCase: true, out ECharacter result))
			{
				CharacterMenu.selectedCharacter = result;
			}
			int num = (int)CharacterMenu.selectedCharacter;
			if (Session.Local.Character != num && (num != _sentCharacter || !(Time.unscaledTime - _sentAt < 2f)))
			{
				_sentCharacter = num;
				_sentAt = Time.unscaledTime;
				Session.SetCharacter(num);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MainMenu), "GoToMapSelection")]
		private static bool BeforeMapSelection(MainMenu __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!Session.Active || RunSync.InRun || _choosingMap)
			{
				return true;
			}
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(67, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[MenuLobby] picked ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ECharacter>(CharacterMenu.selectedCharacter);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", back to the lobby instead of the map selection");
			}
			logger.LogInfo(val);
			__instance.GoToMenu();
			_open = true;
			_shown = string.Empty;
			return false;
		}

		internal static void PickCharacterForTest()
		{
			PickCharacter();
		}

		internal static void RefreshForTest()
		{
			_shown = string.Empty;
		}

		internal static bool ClickForTest(string startsWith)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			foreach (Button componentsInChild in ((Component)_content).GetComponentsInChildren<Button>())
			{
				TextMeshProUGUI componentInChildren = ((Component)componentsInChild).GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null && ((TMP_Text)componentInChildren).text.StartsWith(startsWith))
				{
					ExecuteEvents.Execute<IPointerClickHandler>(((Component)componentsInChild).gameObject, (BaseEventData)new PointerEventData(EventSystem.current), ExecuteEvents.pointerClickHandler);
					return true;
				}
			}
			return false;
		}

		internal static List<string> ReportForTest()
		{
			//IL_0034: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>(4L);
			_windowRect.GetWorldCorners(val);
			DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(47, 8);
			defaultInterpolatedStringHandler.AppendLiteral("window [");
			defaultInterpolatedStringHandler.AppendFormatted(((Il2CppArrayBase<Vector3>)(object)val)[0].x, "0");
			defaultInterpolatedStringHandler.AppendLiteral(",");
			defaultInterpolatedStringHandler.AppendFormatted(((Il2CppArrayBase<Vector3>)(object)val)[0].y, "0");
			defaultInterpolatedStringHandler.AppendLiteral(" .. ");
			defaultInterpolatedStringHandler.AppendFormatted(((Il2CppArrayBase<Vector3>)(object)val)[2].x, "0");
			defaultInterpolatedStringHandler.AppendLiteral(",");
			defaultInterpolatedStringHandler.AppendFormatted(((Il2CppArrayBase<Vector3>)(object)val)[2].y, "0");
			defaultInterpolatedStringHandler.AppendLiteral("] on a ");
			defaultInterpolatedStringHandler.AppendFormatted(Screen.width);
			defaultInterpolatedStringHandler.AppendLiteral("x");
			defaultInterpolatedStringHandler.AppendFormatted(Screen.height);
			defaultInterpolatedStringHandler.AppendLiteral(" screen, height ");
			Rect rect = _windowRect.rect;
			defaultInterpolatedStringHandler.AppendFormatted(((Rect)(ref rect)).height, "0");
			defaultInterpolatedStringHandler.AppendLiteral(", wanted ");
			defaultInterpolatedStringHandler.AppendFormatted(80f + _contentHeight, "0");
			list.Add(defaultInterpolatedStringHandler.ToStringAndClear());
			List<(float, float)> list2 = new List<(float, float)>();
			for (int i = 0; i < ((Transform)_content).childCount; i++)
			{
				RectTransform val2 = ((Il2CppObjectBase)((Transform)_content).GetChild(i)).TryCast<RectTransform>();
				if ((Object)(object)val2 == (Object)null || !((Component)val2).gameObject.activeSelf)
				{
					continue;
				}
				val2.GetWorldCorners(val);
				float top = ((Il2CppArrayBase<Vector3>)(object)val)[1].y;
				float bottom = ((Il2CppArrayBase<Vector3>)(object)val)[0].y;
				bool flag = list2.Any<(float, float)>(((float Top, float Bottom) r) => top > r.Bottom + 0.5f && bottom < r.Top - 0.5f);
				list2.Add((top, bottom));
				List<string> list3 = new List<string>();
				foreach (TextMeshProUGUI componentsInChild in ((Component)val2).GetComponentsInChildren<TextMeshProUGUI>())
				{
					((TMP_Text)componentsInChild).ForceMeshUpdate(false, false);
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(3, 4);
					defaultInterpolatedStringHandler2.AppendLiteral("'");
					defaultInterpolatedStringHandler2.AppendFormatted(((TMP_Text)componentsInChild).GetParsedText());
					defaultInterpolatedStringHandler2.AppendLiteral("' ");
					defaultInterpolatedStringHandler2.AppendFormatted(((TMP_Text)componentsInChild).fontSize, "0");
					defaultInterpolatedStringHandler2.AppendFormatted(((TMP_Text)componentsInChild).isTextOverflowing ? " CUT" : string.Empty);
					float preferredHeight = ((TMP_Text)componentsInChild).preferredHeight;
					rect = ((TMP_Text)componentsInChild).rectTransform.rect;
					string value;
					if (!(preferredHeight > ((Rect)(ref rect)).height + 1f))
					{
						value = string.Empty;
					}
					else
					{
						DefaultInterpolatedStringHandler defaultInterpolatedStringHandler3 = new DefaultInterpolatedStringHandler(8, 2);
						defaultInterpolatedStringHandler3.AppendLiteral(" TALL(");
						defaultInterpolatedStringHandler3.AppendFormatted(((TMP_Text)componentsInChild).preferredHeight, "0");
						defaultInterpolatedStringHandler3.AppendLiteral(">");
						rect = ((TMP_Text)componentsInChild).rectTransform.rect;
						defaultInterpolatedStringHandler3.AppendFormatted(((Rect)(ref rect)).height, "0");
						defaultInterpolatedStringHandler3.AppendLiteral(")");
						value = defaultInterpolatedStringHandler3.ToStringAndClear();
					}
					defaultInterpolatedStringHandler2.AppendFormatted(value);
					list3.Add(defaultInterpolatedStringHandler2.ToStringAndClear());
				}
				list.Add($"row y {bottom:0}..{top:0}{(flag ? " OVERLAP" : string.Empty)}: {string.Join(" | ", list3)}");
			}
			return list;
		}

		private static void PickCharacter()
		{
			MainMenu val = Object.FindObjectOfType<MainMenu>();
			if (!((Object)(object)val == (Object)null))
			{
				_open = false;
				val.GoToCharacterSelection();
			}
		}

		internal static string CharacterName(int character)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (character >= 0)
			{
				return Regex.Replace(((object)(ECharacter)character/*cast due to .constrained prefix*/).ToString(), "(?<=[a-z])(?=[A-Z])", " ");
			}
			return "?";
		}

		internal static void Toggle()
		{
			_open = !_open;
		}

		internal static void Close()
		{
			_open = false;
		}

		private static void Build()
		{
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			if (_failed)
			{
				return;
			}
			GameObject val = GameObject.Find("UI/Tabs/Menu/Content/Main");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			bool flag = default(bool);
			try
			{
				Transform val2 = val.transform.Find("Buttons");
				Transform val3 = ((val2 != null) ? val2.Find("B_Shop") : null);
				Transform val4 = val.transform.Find("ExtraButtons/B_Credits");
				Transform val5 = val.transform.Find("W_Leaderboards");
				if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null)
				{
					throw new InvalidOperationException("menu layout changed (B_Shop, B_Credits or W_Leaderboards missing)");
				}
				Transform obj = val5.Find("Header/Header/Content/Title/T_Title");
				object font;
				if (obj == null)
				{
					font = null;
				}
				else
				{
					TextMeshProUGUI component = ((Component)obj).GetComponent<TextMeshProUGUI>();
					font = ((component != null) ? ((TMP_Text)component).font : null);
				}
				_font = (TMP_FontAsset)font;
				_leaderboards = ((Component)val5).gameObject;
				_menuButton = CloneButton(((Component)val3).gameObject, val2, "B_BonkSquad", "Co-op", Toggle);
				Transform val6 = val2.Find("B_Play");
				_menuButton.transform.SetSiblingIndex(((Object)(object)val6 != (Object)null) ? (val6.GetSiblingIndex() + 1) : val3.GetSiblingIndex());
				_menuButtonText = _menuButton.GetComponentInChildren<TextMeshProUGUI>();
				RectTransform component2 = _menuButton.GetComponent<RectTransform>();
				component2.sizeDelta = new Vector2(236f, component2.sizeDelta.y);
				FitLabel(_menuButtonText, 0f);
				_buttonTemplate = ((Component)val4).gameObject;
				BuildWindow(val.transform, val5);
				_shown = string.Empty;
				_clickAt = (Plugin.DebugOpenLobby.Value ? (Time.unscaledTime + 2f) : (-1f));
				List<string> list = new List<string>();
				for (int i = 0; i < val2.childCount; i++)
				{
					list.Add(((Object)val2.GetChild(i)).name + (((Component)val2.GetChild(i)).gameObject.activeSelf ? "" : "(off)"));
				}
				ManualLogSource logger = Plugin.Logger;
				BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[MenuLobby] added to the main menu: ");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(string.Join(", ", list));
				}
				logger.LogInfo(val7);
			}
			catch (Exception ex)
			{
				_failed = true;
				_menuButton = null;
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val8 = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val8).AppendLiteral("[MenuLobby] couldn't build the menu lobby, F7 still works: ");
					((BepInExLogInterpolatedStringHandler)val8).AppendFormatted<Exception>(ex);
				}
				logger2.LogError(val8);
			}
		}

		private static void BuildWindow(Transform parent, Transform leaderboards)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_007b: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Expected O, but got Unknown
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)leaderboards).GetComponent<RectTransform>();
			_window = new GameObject("W_BonkSquad");
			_windowRect = _window.AddComponent<RectTransform>();
			((Transform)_windowRect).SetParent(parent, false);
			_windowRect.anchorMin = component.anchorMin;
			_windowRect.anchorMax = component.anchorMax;
			_windowRect.pivot = new Vector2(1f, 0f);
			RectTransform windowRect = _windowRect;
			Vector2 anchoredPosition = component.anchoredPosition;
			float num = 1f - component.pivot.x;
			Rect rect = component.rect;
			float num2 = num * ((Rect)(ref rect)).width;
			float num3 = 0f - component.pivot.y;
			rect = component.rect;
			windowRect.anchoredPosition = anchoredPosition + new Vector2(num2, num3 * ((Rect)(ref rect)).height);
			RectTransform windowRect2 = _windowRect;
			rect = component.rect;
			windowRect2.sizeDelta = new Vector2(520f, ((Rect)(ref rect)).height);
			((Graphic)CopyImage(leaderboards.Find("Shadow"), _window.transform, "Shadow")).rectTransform.sizeDelta = new Vector2(40f, 40f);
			((Graphic)Fill(_window.transform, "Background")).color = new Color(0.145f, 0.165f, 0.155f, 1f);
			Top(((Graphic)CopyImage(leaderboards.Find("Header/Header/Background"), _window.transform, "HeaderBackground")).rectTransform, 80f);
			CopyImage(leaderboards.Find("Header/Header/Border"), _window.transform, "HeaderBorder");
			Top(((Component)_window.transform.Find("HeaderBorder")).GetComponent<RectTransform>(), 80f);
			TextMeshProUGUI val = Text(_window.transform, "Co-op <size=70%><color=#C8D2CC>BonkSquad 0.2.13</color></size>", 30f, Color.white);
			((TMP_Text)val).alignment = (TextAlignmentOptions)514;
			Top(((TMP_Text)val).rectTransform, 80f);
			((TMP_Text)val).rectTransform.offsetMin = new Vector2(20f, ((TMP_Text)val).rectTransform.offsetMin.y);
			((TMP_Text)val).rectTransform.offsetMax = new Vector2(-70f, ((TMP_Text)val).rectTransform.offsetMax.y);
			GameObject val2 = new GameObject("Content");
			_content = val2.AddComponent<RectTransform>();
			((Transform)_content).SetParent(_window.transform, false);
			_content.anchorMin = Vector2.zero;
			_content.anchorMax = Vector2.one;
			_content.offsetMin = new Vector2(0f, 0f);
			_content.offsetMax = new Vector2(0f, -80f);
			VerticalLayoutGroup obj = val2.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).padding = new RectOffset
			{
				left = 22,
				right = 22,
				top = 14,
				bottom = 14
			};
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((Graphic)CopyImage(leaderboards.Find("Header/Border"), _window.transform, "Border")).raycastTarget = false;
			RectTransform component2 = CloneButton(_buttonTemplate, _window.transform, "B_Close", "X", Close).GetComponent<RectTransform>();
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(1f, 1f);
			component2.pivot = val3;
			Vector2 anchorMin = (component2.anchorMax = val3);
			component2.anchorMin = anchorMin;
			component2.anchoredPosition = new Vector2(-14f, -14f);
			component2.sizeDelta = new Vector2(52f, 52f);
			_window.SetActive(false);
		}

		private static Image CopyImage(Transform source, Transform parent, string name)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Image val = (((Object)(object)source != (Object)null) ? ((Component)source).GetComponent<Image>() : null);
			Image val2 = Fill(parent, name);
			if ((Object)(object)val != (Object)null)
			{
				val2.sprite = val.sprite;
				val2.type = val.type;
				((Graphic)val2).color = ((Graphic)val).color;
				val2.pixelsPerUnitMultiplier = val.pixelsPerUnitMultiplier;
			}
			return val2;
		}

		private static Image Fill(Transform parent, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0030: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent(parent, false);
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			Vector2 offsetMin = (obj.offsetMax = Vector2.zero);
			obj.offsetMin = offsetMin;
			return val.AddComponent<Image>();
		}

		private static void Top(RectTransform rect, float height)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(0f, 1f);
			rect.anchorMax = new Vector2(1f, 1f);
			rect.pivot = new Vector2(0.5f, 1f);
			rect.anchoredPosition = Vector2.zero;
			rect.sizeDelta = new Vector2(0f, height);
		}

		private static TextMeshProUGUI Text(Transform parent, string text, float size, Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("T_Text");
			((Transform)val.AddComponent<RectTransform>()).SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)_font != (Object)null)
			{
				((TMP_Text)val2).font = _font;
			}
			((TMP_Text)val2).fontSize = size;
			((Graphic)val2).color = color;
			((TMP_Text)val2).enableWordWrapping = true;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).text = text;
			return val2;
		}

		private static GameObject CloneButton(GameObject template, Transform parent, string name, string text, Action onClick)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("BonkSquad.Holder");
			val.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(template, val.transform);
			((Object)val2).name = name;
			foreach (MonoBehaviour componentsInChild in val2.GetComponentsInChildren<MonoBehaviour>(true))
			{
				if (Strip.Contains(((MemberInfo)((Object)componentsInChild).GetIl2CppType()).Name))
				{
					Object.DestroyImmediate((Object)(object)componentsInChild);
				}
			}
			Transform[] array = ((IEnumerable<Transform>)val2.GetComponentsInChildren<Transform>(true)).ToArray();
			foreach (Transform val3 in array)
			{
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val2.transform && (((Object)val3).name.StartsWith("Alert") || ((Object)val3).name.StartsWith("Icon")))
				{
					Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
				}
			}
			TextMeshProUGUI componentInChildren = val2.GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((TMP_Text)componentInChildren).text = text;
				((TMP_Text)componentInChildren).rectTransform.anchoredPosition = new Vector2(0f, ((TMP_Text)componentInChildren).rectTransform.anchoredPosition.y);
			}
			Button component = val2.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Expected O, but got Unknown
				try
				{
					onClick();
				}
				catch (Exception ex)
				{
					ManualLogSource logger = Plugin.Logger;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(14, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[MenuLobby] ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<Exception>(ex);
					}
					logger.LogError(val4);
				}
			}));
			val2.transform.SetParent(parent, false);
			Object.Destroy((Object)(object)val);
			return val2;
		}

		private static void Refresh()
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<ulong, TextMeshProUGUI> ping in Pings)
			{
				if ((Object)(object)ping.Value != (Object)null && Session.Players.TryGetValue(ping.Key, out var value))
				{
					((TMP_Text)ping.Value).text = PingText(value);
				}
			}
			string text = Describe();
			if (!(text == _shown) && !((Object)(object)_content == (Object)null))
			{
				_shown = text;
				for (int num = ((Transform)_content).childCount - 1; num >= 0; num--)
				{
					GameObject gameObject = ((Component)((Transform)_content).GetChild(num)).gameObject;
					gameObject.SetActive(false);
					Object.Destroy((Object)(object)gameObject);
				}
				Pings.Clear();
				_contentHeight = 28f;
				_rows = 0;
				switch (LobbyManager.Current)
				{
				case LobbyManager.State.Idle:
					Idle();
					break;
				case LobbyManager.State.Creating:
				case LobbyManager.State.Joining:
					Label(LobbyManager.Status, 24f, Color.white, 2);
					Buttons(("Cancel", LobbyManager.Leave));
					break;
				case LobbyManager.State.InSession:
					InSession();
					break;
				}
				if (LobbyManager.Current != LobbyManager.State.InSession && LobbyManager.Status.Length > 0)
				{
					Label(LobbyManager.Status, 20f, Dim, 2);
				}
				_windowRect.sizeDelta = new Vector2(520f, 80f + _contentHeight);
			}
		}

		private static string Describe()
		{
			string value = string.Join("|", from p in Session.Players.Values
				orderby p.Slot
				select $"{p.Name}{p.Ready}{p.Character}");
			string value2 = string.Join("|", LobbyManager.FriendLobbies.Select((LobbyManager.FriendLobby l) => l.Name + l.Version));
			string value3 = (((Object)(object)_pending != (Object)null) ? string.Join("|", from p in NotReady()
				select p.Name) : "-");
			return $"{LobbyManager.Current}/{LobbyManager.Status}/{Session.Connected}/{value}/{value2}/{value3}/{MonsterScaling.Key}";
		}

		private static void Idle()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			Buttons(("Create lobby", LobbyManager.HostSteam));
			Label("Open lobbies of friends", 22f, Gold);
			if (LobbyManager.FriendLobbies.Count == 0)
			{
				Label("None found. Invite friends or get invited.", 20f, Dim);
			}
			foreach (LobbyManager.FriendLobby item in LobbyManager.FriendLobbies.Take(4).ToList())
			{
				if (item.Version == LobbyManager.LobbyVersion)
				{
					ulong id = item.Lobby;
					Buttons(("Join: " + item.Name, delegate
					{
						LobbyManager.JoinSteam(id);
					}));
				}
				else
				{
					Label(item.Name + ": " + ((item.Version.Length == 0) ? "not a BonkSquad lobby" : ("version " + item.Version)), 20f, Dim);
				}
			}
			Label($"Direct connection over LAN/UDP: {Plugin.LobbyKey.Value}", 18f, Dim);
		}

		private static void InSession()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			string text = Session.Transport?.Name ?? "?";
			Label(Session.IsHost ? ("You are the host (" + text + ")") : (Session.Connected ? ("Connected (" + text + ")") : LobbyManager.Status), 22f, Gold);
			foreach (Player item2 in Session.Players.Values.OrderBy((Player p) => p.Slot))
			{
				PlayerRow(item2);
			}
			Label("Monsters", 22f, Gold);
			string text2 = $"Difficulty: {MonsterScaling.Difficulty}";
			string text3 = "Per player: " + (MonsterScaling.PerPlayer ? "on" : "off");
			if (Session.IsHost)
			{
				Buttons((text2, MonsterScaling.NextDifficulty), (text3, MonsterScaling.TogglePerPlayer));
			}
			else
			{
				RectTransform row = Row(26f);
				Cell(row, text2, 20f, Color.white, 0f, 238f, 0f, 1f, (TextAlignmentOptions)513);
				Cell(row, text3, 20f, Color.white, 238f, 238f, 0f, 1f, (TextAlignmentOptions)513);
			}
			Label(MonsterScaling.Summary(), 18f, Dim);
			if ((Object)(object)_pending != (Object)null)
			{
				Label(_pendingMap + ": waiting for " + string.Join(", ", from p in NotReady()
					select p.Name), 20f, Gold);
				Buttons(("Cancel start", CancelStart));
			}
			bool flag = Session.IsClient && Session.Connected;
			bool ready = Session.Local?.Ready ?? false;
			if (Session.IsHost)
			{
				Buttons(("Character", PickCharacter), ("Choose map", ChooseMap));
			}
			else if (flag)
			{
				Buttons(("Character", PickCharacter), (ready ? "Not ready" : "Ready", delegate
				{
					Session.SetReady(!ready);
				}));
			}
			string item = (Session.IsHost ? "Close lobby" : "Leave lobby");
			if (LobbyManager.LobbyId != 0L)
			{
				Buttons(("Invite friends", LobbyManager.OpenInviteDialog), (item, LobbyManager.Leave));
			}
			else
			{
				Buttons((item, LobbyManager.Leave));
			}
			if (Session.IsHost && (Object)(object)_pending == (Object)null)
			{
				Label("Choose a map to start the run.", 18f, Dim);
			}
			else if (flag)
			{
				Label(ready ? "Waiting for the host." : "Pick your character, then press Ready.", 18f, Dim);
			}
		}

		private static string PingText(Player p)
		{
			if (p.Id != Session.LocalId)
			{
				if (!(p.RttMs < 0f))
				{
					return $"{p.RttMs:0} ms";
				}
				return "…";
			}
			return "you";
		}

		private static void PlayerRow(Player p)
		{
			//IL_003d: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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)
			RectTransform row = Row(48f);
			Portrait(row, p.Character);
			float width = 290f;
			Cell(row, p.Name, 24f, (p.Id == Session.LocalId) ? Gold : Color.white, 56f, width, 0.5f, 1f, (TextAlignmentOptions)513);
			Cell(row, CharacterName(p.Character), 18f, Dim, 56f, width, 0f, 0.5f, (TextAlignmentOptions)513);
			string text = ((p.Id == Session.HostId) ? "<color=#FFD95A>Host</color>" : (p.Ready ? "<color=#7CFC9A>Ready</color>" : "<color=#C8C8C8>Not ready</color>"));
			Cell(row, text, 20f, Color.white, 346f, 130f, 0.5f, 1f, (TextAlignmentOptions)516);
			Pings[p.Id] = Cell(row, PingText(p), 16f, Dim, 346f, 130f, 0f, 0.5f, (TextAlignmentOptions)516);
		}

		private static void Portrait(RectTransform row, int character)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0063: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Portrait");
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent((Transform)(object)row, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0f, 0.5f);
			val2.anchoredPosition = Vector2.zero;
			val2.sizeDelta = new Vector2(48f, 48f);
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).color = new Color(0.07f, 0.08f, 0.08f, 1f);
			((Graphic)obj).raycastTarget = false;
			object obj2;
			if (character < 0)
			{
				obj2 = null;
			}
			else
			{
				DataManager instance = DataManager.Instance;
				if (instance == null)
				{
					obj2 = null;
				}
				else
				{
					CharacterData characterData = instance.GetCharacterData((ECharacter)character);
					obj2 = ((characterData != null) ? characterData.icon : null);
				}
			}
			Texture val4 = (Texture)obj2;
			if (!((Object)(object)val4 == (Object)null))
			{
				GameObject val5 = new GameObject("Icon");
				RectTransform obj3 = val5.AddComponent<RectTransform>();
				((Transform)obj3).SetParent((Transform)(object)val2, false);
				obj3.anchorMin = Vector2.zero;
				obj3.anchorMax = Vector2.one;
				obj3.offsetMin = new Vector2(2f, 2f);
				obj3.offsetMax = new Vector2(-2f, -2f);
				RawImage obj4 = val5.AddComponent<RawImage>();
				obj4.texture = val4;
				((Graphic)obj4).raycastTarget = false;
			}
		}

		private static RectTransform Row(float height)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row");
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent((Transform)(object)_content, false);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minHeight = height;
			obj.preferredHeight = height;
			_contentHeight += height + ((_rows++ > 0) ? 8f : 0f);
			return val2;
		}

		private static TextMeshProUGUI Cell(RectTransform row, string text, float size, Color color, float x, float width, float yMin, float yMax, TextAlignmentOptions align)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_003e: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI obj = Text((Transform)(object)row, text, size, color);
			RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, yMin);
			rectTransform.anchorMax = new Vector2(0f, yMax);
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.anchoredPosition = new Vector2(x, 0f);
			rectTransform.sizeDelta = new Vector2(width, 0f);
			ShrinkToFit(obj, align);
			return obj;
		}

		private static void ShrinkToFit(TextMeshProUGUI text, TextAlignmentOptions align)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			float fontSize = ((TMP_Text)text).fontSize;
			((TMP_Text)text).alignment = align;
			((TMP_Text)text).enableWordWrapping = false;
			((TMP_Text)text).overflowMode = (TextOverflowModes)1;
			((TMP_Text)text).fontSizeMax = fontSize;
			((TMP_Text)text).fontSizeMin = Mathf.Min(14f, fontSize);
			((TMP_Text)text).enableAutoSizing = true;
		}

		private static void Label(string text, float size, Color color, int lines = 1)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)Cell(Row(Mathf.Ceil(size * 1.25f) * (float)lines), text, size, color, 0f, 476f, 0f, 1f, (TextAlignmentOptions)513)).enableWordWrapping = lines > 1;
		}

		private static void Buttons(params (string Text, Action OnClick)[] buttons)
		{
			//IL_004d: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			RectTransform parent = Row(50f);
			for (int i = 0; i < buttons.Length; i++)
			{
				GameObject obj = CloneButton(_buttonTemplate, (Transform)(object)parent, "B_Row", buttons[i].Text, buttons[i].OnClick);
				RectTransform component = obj.GetComponent<RectTransform>();
				component.anchorMin = new Vector2((float)i / (float)buttons.Length, 0f);
				component.anchorMax = new Vector2(((float)i + 1f) / (float)buttons.Length, 1f);
				component.pivot = new Vector2(0.5f, 0.5f);
				component.offsetMin = new Vector2((i > 0) ? 4f : 0f, 0f);
				component.offsetMax = new Vector2((i < buttons.Length - 1) ? (-4f) : 0f, 0f);
				TextMeshProUGUI componentInChildren = obj.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).fontSize = 22f;
					FitLabel(componentInChildren, 10f);
					ShrinkToFit(componentInChildren, (TextAlignmentOptions)514);
				}
			}
		}

		private static void FitLabel(TextMeshProUGUI label, float inset)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)label).enableWordWrapping = false;
			((TMP_Text)label).rectTransform.anchorMin = Vector2.zero;
			((TMP_Text)label).rectTransform.anchorMax = Vector2.one;
			((TMP_Text)label).rectTransform.offsetMin = new Vector2(inset, ((TMP_Text)label).rectTransform.offsetMin.y);
			((TMP_Text)label).rectTransform.offsetMax = new Vector2(0f - inset, ((TMP_Text)label).rectTransform.offsetMax.y);
			((TMP_Text)label).alignment = (TextAlignmentOptions)514;
		}
	}
	internal static class PartyPanel
	{
		private const float Width = 220f;

		private const float RowHeight = 34f;

		private static GUIStyle _name;

		private static GUIStyle _small;

		private static readonly Color Back = new Color(0f, 0f, 0f, 0.55f);

		private static readonly Color BarBack = new Color(0.25f, 0.08f, 0.08f, 0.9f);

		private st