Decompiled source of GungeonTogether 3Player v0.10.8

BepInEx/plugins/GungeonTogether.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dungeonator;
using GungeonTogether.Networking;
using GungeonTogether.Networking.Enums;
using GungeonTogether.Networking.Interfaces;
using GungeonTogether.Networking.Packets;
using GungeonTogether.Networking.Players;
using GungeonTogether.Networking.Serialization;
using GungeonTogether.Networking.Steam;
using GungeonTogether.Networking.Sync;
using GungeonTogether.Systems.Logging;
using GungeonTogether.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("GungeonTogether")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Gungeon Together Mod")]
[assembly: AssemblyFileVersion("0.10.8.0")]
[assembly: AssemblyInformationalVersion("0.10.8+61faed448ca85989631833cf2517c4613d42123c")]
[assembly: AssemblyProduct("GungeonTogether")]
[assembly: AssemblyTitle("GungeonTogether")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.10.8.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;
		}
	}
}
public class NetworkEntityManager
{
	private static NetworkEntityManager _instance;

	private int _nextId = 1;

	private Dictionary<int, object> _entities = new Dictionary<int, object>();

	private Dictionary<int, GameObject> _remoteEntities = new Dictionary<int, GameObject>();

	public static NetworkEntityManager Instance => _instance ?? (_instance = new NetworkEntityManager());

	public int AssignId(object entity)
	{
		int num = _nextId++;
		_entities[num] = entity;
		return num;
	}

	public object GetEntity(int id)
	{
		if (!_entities.TryGetValue(id, out var value))
		{
			return null;
		}
		return value;
	}

	public void AddRemote(int id, GameObject go)
	{
		_remoteEntities[id] = go;
	}

	public bool IsRemoteObject(GameObject go)
	{
		return _remoteEntities.ContainsValue(go);
	}

	public GameObject GetRemote(int id)
	{
		if (!_remoteEntities.TryGetValue(id, out var value))
		{
			return null;
		}
		return value;
	}

	public void RemoveRemote(int id)
	{
		if (_remoteEntities.TryGetValue(id, out var value))
		{
			Object.Destroy((Object)(object)value);
		}
		_remoteEntities.Remove(id);
	}

	public void Clear()
	{
		foreach (KeyValuePair<int, GameObject> remoteEntity in _remoteEntities)
		{
			Object.Destroy((Object)(object)remoteEntity.Value);
		}
		_remoteEntities.Clear();
		_entities.Clear();
		_nextId = 1;
	}
}
public class PlayerJoinPacket : INetworkPacket
{
	public ulong PlayerId;

	public Vector2 Position;

	public float Rotation;

	public PacketType Type => PacketType.PlayerJoin;

	public void Serialize(BinaryWriter writer)
	{
		writer.Write(PlayerId);
		writer.Write(Position.x);
		writer.Write(Position.y);
		writer.Write(Rotation);
	}

	public void Deserialize(BinaryReader reader)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		PlayerId = reader.ReadUInt64();
		Position = new Vector2(reader.ReadSingle(), reader.ReadSingle());
		Rotation = reader.ReadSingle();
	}
}
public class PlayerLeavePacket : INetworkPacket
{
	public ulong PlayerId;

	public PacketType Type => PacketType.PlayerLeave;

	public void Serialize(BinaryWriter writer)
	{
		writer.Write(PlayerId);
	}

	public void Deserialize(BinaryReader reader)
	{
		PlayerId = reader.ReadUInt64();
	}
}
public class RoomSyncManager : MonoBehaviour
{
	private static RoomSyncManager _instance;

	private string _currentRoomName = "";

	private float _lastSyncTime;

	private float _lastSpawnRefreshTime;

	private bool _lastRoomSealed;

	private bool _hasRoomState;

	private bool _cameraOverrideOwned;

	private const float SYNC_INTERVAL = 0.2f;

	private const float SPAWN_REFRESH_INTERVAL = 2f;

	private Dictionary<Component, int> _enemyIdMap = new Dictionary<Component, int>();

	public static RoomSyncManager Instance => _instance ?? (_instance = new GameObject("RoomSyncManager").AddComponent<RoomSyncManager>());

	private void LateUpdate()
	{
		UpdateSharedCameraBounds();
	}

	private void Awake()
	{
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
	}

	private void Start()
	{
		ETGReflectionHelper.Initialise();
	}

	private void Update()
	{
		if ((NetworkManager.Instance.IsHost || NetworkManager.Instance.IsClient) && NetworkManager.Instance.IsHost)
		{
			SyncHost();
		}
	}

	private void SyncHost()
	{
		object currentRoomHandler = ETGReflectionHelper.GetCurrentRoomHandler();
		if (currentRoomHandler == null)
		{
			return;
		}
		RoomHandler val = (RoomHandler)((currentRoomHandler is RoomHandler) ? currentRoomHandler : null);
		if (val != null)
		{
			string text = val.GetRoomName() + "@" + val.area.basePosition.x + "," + val.area.basePosition.y;
			if (text != _currentRoomName)
			{
				_currentRoomName = text;
				SpawnAndBroadcastEnemies(val);
				BroadcastRoomState(val, reliable: true);
			}
			else if (!_hasRoomState || val.IsSealed != _lastRoomSealed)
			{
				BroadcastRoomState(val, reliable: true);
			}
			if (Time.time - _lastSyncTime > 0.2f)
			{
				_lastSyncTime = Time.time;
				SyncEnemyStates();
			}
		}
	}

	private void SpawnAndBroadcastEnemies(RoomHandler room)
	{
		//IL_0037: 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_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		foreach (object activeEnemy in ETGReflectionHelper.GetActiveEnemies())
		{
			Component val = (Component)((activeEnemy is Component) ? activeEnemy : null);
			if (!((Object)(object)val == (Object)null))
			{
				int orAssignEnemyId = GetOrAssignEnemyId(val);
				Vector3 position = val.transform.position;
				float z = val.transform.eulerAngles.z;
				float enemyHealth = ETGReflectionHelper.GetEnemyHealth(val);
				AIActor val2 = (AIActor)(object)((val is AIActor) ? val : null);
				if ((Object)(object)val2 != (Object)null)
				{
					EnemyProjectileSyncManager.Instance.TrackHostEnemy(orAssignEnemyId, val2);
				}
				string prefabName = (((Object)(object)val2 != (Object)null) ? val2.EnemyGuid : ((Object)val).name);
				EnemySpawnPacket packet = new EnemySpawnPacket
				{
					EnemyId = orAssignEnemyId,
					PrefabName = prefabName,
					Position = new Vector2(position.x, position.y),
					Rotation = z,
					Health = enemyHealth,
					RoomIdentifier = GetRoomIdentifier(((Object)(object)val2 != (Object)null) ? val2.ParentRoom : room)
				};
				NetworkManager.Instance.Host.Broadcast(packet, 0uL);
			}
		}
	}

	private void SyncEnemyStates()
	{
		//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_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: 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_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		bool flag = Time.time - _lastSpawnRefreshTime > 2f;
		if (flag)
		{
			_lastSpawnRefreshTime = Time.time;
		}
		foreach (object allActiveEnemy in GetAllActiveEnemies())
		{
			Component val = (Component)((allActiveEnemy is Component) ? allActiveEnemy : null);
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			bool num = !_enemyIdMap.ContainsKey(val);
			int orAssignEnemyId = GetOrAssignEnemyId(val);
			Vector3 position = val.transform.position;
			float z = val.transform.eulerAngles.z;
			float enemyHealth = ETGReflectionHelper.GetEnemyHealth(val);
			int enemyAIState = ETGReflectionHelper.GetEnemyAIState(val);
			if (num || flag)
			{
				AIActor val2 = (AIActor)(object)((val is AIActor) ? val : null);
				if ((Object)(object)val2 != (Object)null)
				{
					EnemyProjectileSyncManager.Instance.TrackHostEnemy(orAssignEnemyId, val2);
				}
				NetworkManager.Instance.Host.Broadcast(new EnemySpawnPacket
				{
					EnemyId = orAssignEnemyId,
					PrefabName = (((Object)(object)val2 != (Object)null) ? val2.EnemyGuid : ((Object)val).name),
					Position = new Vector2(position.x, position.y),
					Rotation = z,
					Health = enemyHealth,
					RoomIdentifier = GetRoomIdentifier(((Object)(object)val2 != (Object)null) ? val2.ParentRoom : null)
				}, 0uL);
			}
			EnemyStatePacket packet = new EnemyStatePacket
			{
				EnemyId = orAssignEnemyId,
				Position = new Vector2(position.x, position.y),
				Rotation = z,
				Health = enemyHealth,
				AIState = enemyAIState,
				Velocity = ((val is AIActor && (Object)(object)((BraveBehaviour)(AIActor)val).specRigidbody != (Object)null) ? ((BraveBehaviour)(AIActor)val).specRigidbody.Velocity : Vector2.zero),
				SpriteId = ((val is AIActor && (Object)(object)((BraveBehaviour)(AIActor)val).sprite != (Object)null) ? ((BraveBehaviour)(AIActor)val).sprite.spriteId : (-1)),
				FlipX = (val is AIActor && (Object)(object)((BraveBehaviour)(AIActor)val).sprite != (Object)null && ((BraveBehaviour)(AIActor)val).sprite.FlipX)
			};
			NetworkManager.Instance.Host.Broadcast(packet, 0uL, reliable: false);
		}
		List<Component> list = new List<Component>();
		foreach (KeyValuePair<Component, int> item in _enemyIdMap)
		{
			Component key = item.Key;
			AIActor val3 = (AIActor)(object)((key is AIActor) ? key : null);
			if ((Object)(object)item.Key == (Object)null || ((Object)(object)val3 != (Object)null && (Object)(object)((BraveBehaviour)val3).healthHaver != (Object)null && ((BraveBehaviour)val3).healthHaver.IsDead))
			{
				NetworkManager.Instance.Host.Broadcast(new EnemyDeathPacket
				{
					EnemyId = item.Value
				}, 0uL);
				list.Add(item.Key);
			}
		}
		foreach (Component item2 in list)
		{
			_enemyIdMap.Remove(item2);
		}
	}

	public void SendSnapshotTo(ulong targetId)
	{
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkManager.Instance.IsHost || NetworkManager.Instance.Host == null)
		{
			return;
		}
		foreach (object allActiveEnemy in GetAllActiveEnemies())
		{
			Component val = (Component)((allActiveEnemy is Component) ? allActiveEnemy : null);
			AIActor val2 = (AIActor)(object)((val is AIActor) ? val : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				int orAssignEnemyId = GetOrAssignEnemyId(val);
				EnemyProjectileSyncManager.Instance.TrackHostEnemy(orAssignEnemyId, val2);
				NetworkManager.Instance.Host.SendPacket(targetId, new EnemySpawnPacket
				{
					EnemyId = orAssignEnemyId,
					PrefabName = val2.EnemyGuid,
					Position = Vector2.op_Implicit(val.transform.position),
					Rotation = val.transform.eulerAngles.z,
					Health = ETGReflectionHelper.GetEnemyHealth(val),
					RoomIdentifier = GetRoomIdentifier(val2.ParentRoom)
				});
			}
		}
		object currentRoomHandler = ETGReflectionHelper.GetCurrentRoomHandler();
		RoomHandler val3 = (RoomHandler)((currentRoomHandler is RoomHandler) ? currentRoomHandler : null);
		if (val3 != null)
		{
			NetworkManager.Instance.Host.SendPacket(targetId, CreateRoomState(val3));
		}
	}

	private void BroadcastRoomState(RoomHandler room, bool reliable)
	{
		_lastRoomSealed = room.IsSealed;
		_hasRoomState = true;
		NetworkManager.Instance.Host.Broadcast(CreateRoomState(room), 0uL, reliable);
	}

	private static RoomStatePacket CreateRoomState(RoomHandler room)
	{
		RoomStatePacket roomStatePacket = new RoomStatePacket();
		roomStatePacket.RoomIdentifier = room.GetRoomName() + "@" + room.area.basePosition.x + "," + room.area.basePosition.y;
		roomStatePacket.IsSealed = room.IsSealed;
		return roomStatePacket;
	}

	public void HandleClientRoomRequest(ulong playerId, RoomChangePacket packet)
	{
	}

	public void ApplyPartyTransition(RoomChangePacket packet)
	{
	}

	private void UpdateSharedCameraBounds()
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)instance.MainCameraController == (Object)null)
		{
			return;
		}
		CameraController mainCameraController = instance.MainCameraController;
		bool num = (NetworkManager.Instance.IsHost || NetworkManager.Instance.IsClient) && !ETGReflectionHelper.IsLevelLoading() && (Object)(object)instance.PrimaryPlayer != (Object)null;
		List<PlayerController> remotePlayerControllers = PlayerManager.Instance.GetRemotePlayerControllers();
		if (!num || remotePlayerControllers.Count == 0)
		{
			ReleaseCameraOverride(mainCameraController);
			return;
		}
		RoomHandler currentRoom = instance.PrimaryPlayer.CurrentRoom;
		Vector2 val = ((GameActor)instance.PrimaryPlayer).CenterPosition;
		Vector2 val2 = val;
		int num2 = 1;
		foreach (PlayerController item in remotePlayerControllers)
		{
			if (!((Object)(object)item == (Object)null) && currentRoom != null && item.CurrentRoom == currentRoom)
			{
				Vector2 centerPosition = ((GameActor)item).CenterPosition;
				val = Vector2.Min(val, centerPosition);
				val2 = Vector2.Max(val2, centerPosition);
				num2++;
			}
		}
		if (num2 < 2)
		{
			ReleaseCameraOverride(mainCameraController);
			return;
		}
		mainCameraController.OverridePlayerOnePosition = val;
		mainCameraController.OverridePlayerTwoPosition = val2;
		mainCameraController.UseOverridePlayerOnePosition = true;
		mainCameraController.UseOverridePlayerTwoPosition = true;
		_cameraOverrideOwned = true;
	}

	private void ReleaseCameraOverride(CameraController camera)
	{
		if (_cameraOverrideOwned)
		{
			_cameraOverrideOwned = false;
			camera.UseOverridePlayerOnePosition = false;
			camera.UseOverridePlayerTwoPosition = false;
		}
	}

	public static RoomHandler FindRoom(string identifier)
	{
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)instance.Dungeon == (Object)null || instance.Dungeon.data == null || instance.Dungeon.data.rooms == null)
		{
			return null;
		}
		foreach (RoomHandler room in instance.Dungeon.data.rooms)
		{
			if (room != null && string.Equals(GetRoomIdentifier(room), identifier, StringComparison.Ordinal))
			{
				return room;
			}
		}
		return null;
	}

	public static string GetRoomIdentifier(RoomHandler room)
	{
		if (room != null && room.area != null)
		{
			return room.GetRoomName() + "@" + room.area.basePosition.x + "," + room.area.basePosition.y;
		}
		return "";
	}

	private static List<object> GetAllActiveEnemies()
	{
		List<object> list = new List<object>();
		if (StaticReferenceManager.AllEnemies == null)
		{
			return list;
		}
		foreach (AIActor allEnemy in StaticReferenceManager.AllEnemies)
		{
			if ((Object)(object)allEnemy != (Object)null && ((Component)allEnemy).gameObject.activeInHierarchy && (Object)(object)((BraveBehaviour)allEnemy).healthHaver != (Object)null && !((BraveBehaviour)allEnemy).healthHaver.IsDead)
			{
				list.Add(allEnemy);
			}
		}
		return list;
	}

	public void ApplyRoomState(RoomStatePacket packet)
	{
		object currentRoomHandler = ETGReflectionHelper.GetCurrentRoomHandler();
		RoomHandler val = (RoomHandler)((currentRoomHandler is RoomHandler) ? currentRoomHandler : null);
		if (val != null && packet != null && string.Equals(val.GetRoomName() + "@" + val.area.basePosition.x + "," + val.area.basePosition.y, packet.RoomIdentifier, StringComparison.Ordinal))
		{
			val.SetRoomActive(true);
			if ((Object)(object)GameManager.Instance.PrimaryPlayer != (Object)null)
			{
				val.OnBecameVisible(GameManager.Instance.PrimaryPlayer);
			}
			if (packet.IsSealed && !val.IsSealed)
			{
				val.SealRoom();
			}
			else if (!packet.IsSealed && val.IsSealed)
			{
				val.UnsealRoom();
			}
		}
	}

	private int GetOrAssignEnemyId(Component enemy)
	{
		if (_enemyIdMap.TryGetValue(enemy, out var value))
		{
			return value;
		}
		value = NetworkEntityManager.Instance.AssignId(enemy);
		_enemyIdMap[enemy] = value;
		return value;
	}

	public void ResetSession()
	{
		_currentRoomName = "";
		_lastSyncTime = 0f;
		_lastSpawnRefreshTime = 0f;
		_hasRoomState = false;
		_cameraOverrideOwned = false;
		_enemyIdMap.Clear();
	}
}
namespace GungeonTogether.UI
{
	public class IsaacHud : MonoBehaviour
	{
		private class Entry
		{
			public ulong Id;

			public string Name;

			public bool Local;

			public PlayerController Controller;

			public Color Color;
		}

		private class View
		{
			public float Health;

			public float MaxHealth;

			public float Armor;

			public int Blanks;

			public int Keys;

			public int Currency;

			public int Ammo;

			public int MaxAmmo;

			public bool InfiniteAmmo;

			public bool Downed;

			public bool HasData;

			public float Age;

			public int PingMs = -1;

			public Gun Gun;

			public PlayerItem Active;

			public List<PassiveItem> Passives;
		}

		private delegate Color PixelColor(int x, int y);

		private static IsaacHud _instance;

		private const string HideReason = "gungeon-together-hud";

		private const float RemoteForgetSeconds = 20f;

		private const int HeartsPerRow = 6;

		private const int PassivesPerRow = 10;

		private const int MaxPassiveRows = 2;

		private static readonly Color[] PlayerColors = (Color[])(object)new Color[4]
		{
			new Color(0.96f, 0.66f, 0.24f),
			new Color(0.35f, 0.69f, 1f),
			new Color(0.48f, 0.85f, 0.48f),
			new Color(0.85f, 0.42f, 0.85f)
		};

		private bool _userEnabled = true;

		private bool _nativeHidden;

		private bool _active;

		private bool _hiddenByGame;

		private float _nextRefresh;

		private float _nextSessionCheck;

		private bool _sessionWantsHud;

		private float _nextNameRefresh;

		private float _hintUntil;

		private float _nextErrorLog;

		private readonly List<Entry> _entries = new List<Entry>();

		private readonly Dictionary<ulong, string> _names = new Dictionary<ulong, string>();

		private GUIStyle _label;

		private Texture2D _white;

		private Texture2D _heartFull;

		private Texture2D _heartHalf;

		private Texture2D _heartEmpty;

		private Texture2D _shield;

		private Texture2D _blank;

		private Texture2D _key;

		private Texture2D _coin;

		private static FieldInfo _coreHiddenField;

		private static FieldInfo _overridesField;

		private static FieldInfo _baseValueField;

		private static FieldInfo _overrideKeyField;

		private static bool _reflectionTried;

		private static FieldInfo _reloadBarsField;

		private static bool _reloadBarsTried;

		private const float PanelWidth = 248f;

		private const float Pad = 8f;

		private const float NameH = 22f;

		private const float HeartSize = 20f;

		private const float HeartRowH = 23f;

		private const float ConsH = 20f;

		private const float GearH = 36f;

		private const float PassiveSize = 21f;

		private const float PassiveRowH = 23f;

		private const int AlignLeft = 0;

		private const int AlignCenter = 1;

		public static IsaacHud Instance
		{
			get
			{
				//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_0027: Expected O, but got Unknown
				if ((Object)(object)_instance == (Object)null)
				{
					GameObject val = new GameObject("GungeonTogetherHud");
					_instance = val.AddComponent<IsaacHud>();
					Object.DontDestroyOnLoad((Object)val);
				}
				return _instance;
			}
		}

		private void Update()
		{
			try
			{
				if (Input.GetKeyDown((KeyCode)289))
				{
					_userEnabled = !_userEnabled;
					GungeonTogether.Systems.Logging.Debug.Log("[Hud] Isaac-style HUD " + (_userEnabled ? "enabled" : "disabled"));
				}
				if (Time.realtimeSinceStartup >= _nextSessionCheck)
				{
					_nextSessionCheck = Time.realtimeSinceStartup + 0.25f;
					_sessionWantsHud = ShouldBeActive();
				}
				bool flag = _userEnabled && _sessionWantsHud;
				if (flag != _active)
				{
					_active = flag;
					if (flag)
					{
						_hintUntil = Time.realtimeSinceStartup + 12f;
					}
				}
				SetNativeHidden(_active);
				if (_active && Time.realtimeSinceStartup >= _nextRefresh)
				{
					_nextRefresh = Time.realtimeSinceStartup + 0.25f;
					RefreshEntries();
					_hiddenByGame = IsHiddenByGame();
					if (_nativeHidden && !_hiddenByGame)
					{
						RestoreReloadBars();
					}
				}
			}
			catch (Exception e)
			{
				LogErrorThrottled("update", e);
			}
		}

		private static bool ShouldBeActive()
		{
			NetworkManager instance = NetworkManager.Instance;
			if (!instance.IsHost && !instance.IsClient)
			{
				return false;
			}
			if (instance.IsClient && (instance.Client == null || !instance.Client.IsConnected))
			{
				return false;
			}
			if (instance.IsHost && instance.Host == null)
			{
				return false;
			}
			GameManager instance2 = GameManager.Instance;
			if ((Object)(object)instance2 == (Object)null || instance2.IsFoyer || (Object)(object)instance2.PrimaryPlayer == (Object)null)
			{
				return false;
			}
			ulong localSteamId = SteamReflectionHelper.GetLocalSteamId();
			foreach (ulong knownPlayerId in GameplaySyncManager.Instance.GetKnownPlayerIds())
			{
				if (knownPlayerId != localSteamId)
				{
					return true;
				}
			}
			return false;
		}

		private void SetNativeHidden(bool hide)
		{
			if (hide == _nativeHidden)
			{
				return;
			}
			GameUIRoot instance = GameUIRoot.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			try
			{
				if (hide)
				{
					instance.HideCoreUI("gungeon-together-hud");
				}
				else
				{
					instance.ShowCoreUI("gungeon-together-hud");
				}
				_nativeHidden = hide;
			}
			catch (Exception e)
			{
				LogErrorThrottled("native-hud", e);
				_nativeHidden = hide;
			}
		}

		private static void RestoreReloadBars()
		{
			GameUIRoot instance = GameUIRoot.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			try
			{
				if (!_reloadBarsTried)
				{
					_reloadBarsTried = true;
					_reloadBarsField = typeof(GameUIRoot).GetField("m_extantReloadBars", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				List<GameUIReloadBarController> list = (((object)_reloadBarsField != null) ? (_reloadBarsField.GetValue(instance) as List<GameUIReloadBarController>) : null);
				if (list == null)
				{
					return;
				}
				for (int i = 0; i < list.Count; i++)
				{
					if ((Object)(object)list[i] != (Object)null)
					{
						list[i].SetInvisibility(false, "CoreUI");
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (_nativeHidden && (Object)(object)GameUIRoot.Instance != (Object)null)
				{
					GameUIRoot.Instance.ShowCoreUI("gungeon-together-hud");
				}
			}
			catch (Exception)
			{
			}
		}

		private bool IsHiddenByGame()
		{
			GameManager instance = GameManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.IsPaused || instance.IsLoadingLevel)
			{
				return true;
			}
			if (Foyer.DoMainMenu)
			{
				return true;
			}
			GameUIRoot instance2 = GameUIRoot.Instance;
			if ((Object)(object)instance2 == (Object)null)
			{
				return true;
			}
			try
			{
				if (!_reflectionTried)
				{
					_reflectionTried = true;
					_coreHiddenField = typeof(GameUIRoot).GetField("CoreUIHidden", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if ((object)_coreHiddenField != null)
					{
						Type fieldType = _coreHiddenField.FieldType;
						_overridesField = fieldType.GetField("m_overrides", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						_baseValueField = fieldType.GetField("BaseValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					}
				}
				if ((object)_coreHiddenField == null)
				{
					return false;
				}
				object value = _coreHiddenField.GetValue(instance2);
				if (value == null)
				{
					return false;
				}
				if ((object)_baseValueField != null && (bool)_baseValueField.GetValue(value))
				{
					return true;
				}
				IEnumerable enumerable = (((object)_overridesField != null) ? (_overridesField.GetValue(value) as IEnumerable) : null);
				if (enumerable == null)
				{
					return false;
				}
				foreach (object item in enumerable)
				{
					if (item != null)
					{
						if ((object)_overrideKeyField == null)
						{
							_overrideKeyField = item.GetType().GetField("key", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						}
						if ((((object)_overrideKeyField != null) ? (_overrideKeyField.GetValue(item) as string) : null) != "gungeon-together-hud")
						{
							return true;
						}
					}
				}
			}
			catch (Exception e)
			{
				LogErrorThrottled("hidden-check", e);
			}
			return false;
		}

		private void RefreshEntries()
		{
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager instance = NetworkManager.Instance;
			ulong localSteamId = SteamReflectionHelper.GetLocalSteamId();
			ulong num = (instance.IsHost ? localSteamId : ((instance.Client != null) ? instance.Client.HostId : 0));
			List<ulong> list = new List<ulong>();
			list.Add(localSteamId);
			List<ulong> list2 = new List<ulong>();
			foreach (ulong knownPlayerId in GameplaySyncManager.Instance.GetKnownPlayerIds())
			{
				if (knownPlayerId != localSteamId && knownPlayerId != 0L)
				{
					GameplaySyncManager.Instance.TryGetVitals(knownPlayerId, out var _, out var ageSeconds);
					if (!(ageSeconds > 20f) || !((Object)(object)PlayerManager.Instance.GetRemotePlayerController(knownPlayerId) == (Object)null))
					{
						list2.Add(knownPlayerId);
					}
				}
			}
			list2.Sort();
			if (num != 0L && num != localSteamId && list2.Remove(num))
			{
				list.Insert(0, num);
			}
			list.AddRange(list2);
			if (Time.realtimeSinceStartup >= _nextNameRefresh)
			{
				_nextNameRefresh = Time.realtimeSinceStartup + 10f;
				_names.Clear();
			}
			_entries.Clear();
			for (int i = 0; i < list.Count && i < 4; i++)
			{
				ulong num2 = list[i];
				if (!_names.TryGetValue(num2, out var value))
				{
					try
					{
						value = SteamReflectionHelper.GetPlayerName(num2);
					}
					catch (Exception)
					{
						value = null;
					}
					if (string.IsNullOrEmpty(value))
					{
						value = "Oyuncu " + (i + 1);
					}
					_names[num2] = value;
				}
				_entries.Add(new Entry
				{
					Id = num2,
					Name = value,
					Local = (num2 == localSteamId),
					Controller = ((num2 == localSteamId) ? GameManager.Instance.PrimaryPlayer : PlayerManager.Instance.GetRemotePlayerController(num2)),
					Color = PlayerColors[i % PlayerColors.Length]
				});
			}
		}

		private static View BuildView(Entry entry)
		{
			View view = new View();
			PlayerController controller = entry.Controller;
			if (entry.Local && (Object)(object)controller != (Object)null && (Object)(object)((BraveBehaviour)controller).healthHaver != (Object)null)
			{
				view.HasData = true;
				view.Health = ((BraveBehaviour)controller).healthHaver.GetCurrentHealth();
				view.MaxHealth = ((BraveBehaviour)controller).healthHaver.GetMaxHealth();
				view.Armor = ((BraveBehaviour)controller).healthHaver.Armor;
				view.Blanks = controller.Blanks;
				if (controller.carriedConsumables != null)
				{
					view.Keys = controller.carriedConsumables.KeyBullets;
					view.Currency = controller.carriedConsumables.Currency;
				}
				view.Gun = ((GameActor)controller).CurrentGun;
				if ((Object)(object)view.Gun != (Object)null)
				{
					view.Ammo = view.Gun.CurrentAmmo;
					view.MaxAmmo = view.Gun.AdjustedMaxAmmo;
					view.InfiniteAmmo = view.Gun.InfiniteAmmo;
				}
				view.Active = controller.CurrentItem;
				view.Passives = controller.passiveItems;
				view.Age = 0f;
				view.PingMs = NetworkManager.Instance.GetLocalPingMs();
				return view;
			}
			if (GameplaySyncManager.Instance.TryGetVitals(entry.Id, out var vitals, out var ageSeconds))
			{
				view.HasData = true;
				view.Age = ageSeconds;
				view.PingMs = ((NetworkManager.Instance.IsClient && NetworkManager.Instance.Client != null && entry.Id == NetworkManager.Instance.Client.HostId) ? NetworkManager.Instance.GetLocalPingMs() : vitals.PingMs);
				view.Health = vitals.Health;
				view.MaxHealth = vitals.MaxHealth;
				view.Armor = vitals.Armor;
				view.Blanks = vitals.Blanks;
				view.Keys = vitals.Keys;
				view.Currency = vitals.Currency;
				view.Ammo = vitals.CurrentGunAmmo;
				view.MaxAmmo = vitals.MaxAmmo;
				view.InfiniteAmmo = vitals.InfiniteAmmo;
				view.Downed = vitals.IsDowned;
				if (!string.IsNullOrEmpty(vitals.ActiveItemKey) || vitals.ActiveItemId >= 0)
				{
					ref PlayerItem active = ref view.Active;
					PickupObject obj = ModCompatibility.ResolvePickup(vitals.ActiveItemKey, vitals.ActiveItemId);
					active = (PlayerItem)(object)((obj is PlayerItem) ? obj : null);
				}
			}
			else
			{
				view.Age = float.MaxValue;
			}
			if ((Object)(object)controller != (Object)null)
			{
				view.Gun = ((GameActor)controller).CurrentGun;
				view.Passives = controller.passiveItems;
			}
			return view;
		}

		private void OnGUI()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (Event.current == null || (int)Event.current.type != 7 || !_active || _hiddenByGame || _entries.Count == 0)
			{
				return;
			}
			try
			{
				EnsureResources();
				float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 1.6f);
				float num2 = 12f * num;
				for (int i = 0; i < _entries.Count; i++)
				{
					Entry entry = _entries[i];
					View view = BuildView(entry);
					float num3 = 248f * num;
					float num4 = MeasurePanel(view, num);
					float num5 = ((i % 2 == 0) ? num2 : ((float)Screen.width - num2 - num3));
					float num6 = ((i < 2) ? num2 : ((float)Screen.height - num2 - num4));
					DrawPanel(new Rect(num5, num6, num3, num4), entry, view, num);
				}
				if (Time.realtimeSinceStartup < _hintUntil)
				{
					float num7 = 360f * num;
					Rect r = default(Rect);
					((Rect)(ref r))..ctor(((float)Screen.width - num7) / 2f, num2, num7, 24f * num);
					Fill(r, new Color(0f, 0f, 0f, 0.55f));
					Text(r, "F8: Isaac HUD / oyunun HUD'u", new Color(1f, 0.9f, 0.5f), Mathf.RoundToInt(15f * num), 1);
				}
			}
			catch (Exception e)
			{
				LogErrorThrottled("draw", e);
			}
		}

		private static int HeartRows(View view)
		{
			return (Mathf.Clamp(Mathf.CeilToInt(Mathf.Max(view.MaxHealth, 0f)) + Mathf.CeilToInt(Mathf.Max(view.Armor, 0f)), 1, 18) + 6 - 1) / 6;
		}

		private static int PassiveRows(View view)
		{
			int num = CountPassives(view);
			if (num != 0)
			{
				return Mathf.Min(2, (num + 10 - 1) / 10);
			}
			return 0;
		}

		private static int CountPassives(View view)
		{
			if (view.Passives == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < view.Passives.Count; i++)
			{
				if ((Object)(object)view.Passives[i] != (Object)null && (Object)(object)((BraveBehaviour)view.Passives[i]).sprite != (Object)null)
				{
					num++;
				}
			}
			return num;
		}

		private static float MeasurePanel(View view, float s)
		{
			float num = 34f + (float)HeartRows(view) * 23f + 2f + 20f + 4f + 36f;
			int num2 = PassiveRows(view);
			if (num2 > 0)
			{
				num += 6f + (float)num2 * 23f;
			}
			return (num + 8f) * s;
		}

		private void DrawPanel(Rect panel, Entry entry, View view, float s)
		{
			//IL_0034: 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_005c: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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_02c5: Unknown result type (might be due to invalid IL or missing references)
			int num;
			float num2;
			if (!entry.Local)
			{
				if (view.HasData)
				{
					num = ((view.Age > 6f) ? 1 : 0);
					if (num == 0)
					{
						goto IL_0026;
					}
				}
				else
				{
					num = 1;
				}
				num2 = 0.45f;
				goto IL_0032;
			}
			num = 0;
			goto IL_0026;
			IL_0026:
			num2 = 1f;
			goto IL_0032;
			IL_0032:
			float num3 = num2;
			Fill(panel, new Color(0.04f, 0.03f, 0.05f, 0.72f * num3 + 0.1f));
			Color color = entry.Color;
			color.a = (entry.Local ? 1f : (0.75f * num3));
			Border(panel, color, entry.Local ? Mathf.Max(2f, 3f * s) : Mathf.Max(1f, 2f * s));
			float num4 = ((Rect)(ref panel)).x + 8f * s;
			float num5 = ((Rect)(ref panel)).y + 8f * s;
			float num6 = ((Rect)(ref panel)).width - 16f * s;
			Text(text: entry.Local ? (entry.Name + " (SEN)") : entry.Name, r: new Rect(num4, num5, num6 - 44f * s, 22f * s), color: entry.Color, size: Mathf.RoundToInt(17f * s), align: 0);
			if (!entry.Local)
			{
				DrawSignal(new Rect(((Rect)(ref panel)).xMax - 42f * s, num5 + 3f * s, 30f * s, 16f * s), view.PingMs);
			}
			num5 += 26f * s;
			if (view.Downed)
			{
				Text(new Rect(num4, num5, num6, 23f * s), "YERDE - canlandir!", new Color(1f, 0.35f, 0.35f), Mathf.RoundToInt(16f * s), 0);
				num5 += 23f * s;
			}
			else
			{
				DrawHearts(num4, num5, view, s);
				num5 += (float)HeartRows(view) * 23f * s;
			}
			num5 += 2f * s;
			float x = num4;
			x = DrawCounter(x, num5, _blank, view.Blanks, s);
			x = DrawCounter(x, num5, _key, view.Keys, s);
			DrawCounter(x, num5, _coin, view.Currency, s);
			num5 += 24f * s;
			DrawGear(new Rect(num4, num5, num6, 36f * s), view, s);
			num5 += 36f * s;
			int num7 = PassiveRows(view);
			if (num7 > 0)
			{
				num5 += 6f * s;
				DrawPassives(num4, num5, view, num7, s);
			}
			if (num != 0)
			{
				Text(panel, "bağlantı yok", new Color(1f, 0.5f, 0.4f), Mathf.RoundToInt(16f * s), 1);
			}
		}

		private void DrawHearts(float x0, float y0, View view, float s)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, Mathf.CeilToInt(view.MaxHealth));
			int num2 = Mathf.CeilToInt(Mathf.Max(view.Armor, 0f));
			int num3 = Mathf.Min(num + num2, 18);
			for (int i = 0; i < num3; i++)
			{
				Texture2D icon;
				if (i < num)
				{
					float num4 = view.Health - (float)i;
					icon = ((num4 >= 1f) ? _heartFull : ((num4 >= 0.5f) ? _heartHalf : _heartEmpty));
				}
				else
				{
					icon = _shield;
				}
				float num5 = x0 + (float)(i % 6) * 23f * s;
				float num6 = y0 + (float)(i / 6) * 23f * s;
				DrawPixelIcon(icon, new Rect(num5, num6, 20f * s, 20f * s));
			}
		}

		private float DrawCounter(float x, float y, Texture2D icon, int value, float s)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			DrawPixelIcon(icon, new Rect(x, y + 1f * s, 16f * s, 16f * s));
			Text(new Rect(x + 19f * s, y, 44f * s, 20f * s), value.ToString(), Color.white, Mathf.RoundToInt(16f * s), 0);
			return x + 76f * s;
		}

		private void DrawGear(Rect area, View view, float s)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref area)).x, ((Rect)(ref area)).y, 64f * s, ((Rect)(ref area)).height);
			Fill(val, new Color(1f, 1f, 1f, 0.07f));
			DrawTk2dSprite(((Object)(object)view.Gun != (Object)null) ? ((BraveBehaviour)view.Gun).sprite : null, val);
			Text(text: view.InfiniteAmmo ? "INF" : ((view.Ammo >= 0) ? ((view.MaxAmmo > 0) ? (view.Ammo + "/" + view.MaxAmmo) : view.Ammo.ToString()) : "-"), r: new Rect(((Rect)(ref val)).xMax + 6f * s, ((Rect)(ref area)).y, ((Rect)(ref area)).width - ((Rect)(ref val)).width - 48f * s, ((Rect)(ref area)).height), color: Color.white, size: Mathf.RoundToInt(16f * s), align: 0);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref area)).xMax - ((Rect)(ref area)).height, ((Rect)(ref area)).y, ((Rect)(ref area)).height, ((Rect)(ref area)).height);
			Fill(val2, new Color(1f, 1f, 1f, 0.07f));
			if ((Object)(object)view.Active != (Object)null)
			{
				DrawTk2dSprite(((BraveBehaviour)view.Active).sprite, val2);
			}
		}

		private void DrawPassives(float x0, float y0, View view, int rows, float s)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			int num = rows * 10;
			int num2 = CountPassives(view);
			int num3 = 0;
			int num4 = ((num2 > num) ? (num - 1) : num);
			for (int i = 0; i < view.Passives.Count; i++)
			{
				if (num3 >= num4)
				{
					break;
				}
				PassiveItem val = view.Passives[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((BraveBehaviour)val).sprite == (Object)null))
				{
					float num5 = x0 + (float)(num3 % 10) * 22f * s;
					float num6 = y0 + (float)(num3 / 10) * 23f * s;
					DrawTk2dSprite(((BraveBehaviour)val).sprite, new Rect(num5, num6, 21f * s, 21f * s));
					num3++;
				}
			}
			if (num2 > num3)
			{
				float num7 = x0 + (float)(num3 % 10) * 22f * s;
				float num8 = y0 + (float)(num3 / 10) * 23f * s;
				Text(new Rect(num7, num8, 33.600002f * s, 21f * s), "+" + (num2 - num3), Color.white, Mathf.RoundToInt(15f * s), 0);
			}
		}

		private void DrawSignal(Rect r, int pingMs)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			int num = ((pingMs >= 0) ? ((pingMs < 70) ? 4 : ((pingMs < 130) ? 3 : ((pingMs < 220) ? 2 : ((pingMs < 400) ? 1 : 0)))) : 0);
			Color val = ((num >= 3) ? new Color(0.35f, 0.9f, 0.35f) : ((num == 2) ? new Color(0.95f, 0.85f, 0.25f) : new Color(0.95f, 0.3f, 0.25f)));
			float num2 = ((Rect)(ref r)).width / 4f - 2f;
			Rect r2 = default(Rect);
			for (int i = 0; i < 4; i++)
			{
				float num3 = ((Rect)(ref r)).height * (0.35f + 0.65f * (float)(i + 1) / 4f);
				((Rect)(ref r2))..ctor(((Rect)(ref r)).x + (float)i * (num2 + 2f), ((Rect)(ref r)).yMax - num3, num2, num3);
				Fill(r2, (Color)((i < num) ? val : new Color(1f, 1f, 1f, 0.15f)));
			}
		}

		private void Fill(Rect r, Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			Color color = GUI.color;
			GUI.color = c;
			GUI.DrawTexture(r, (Texture)(object)_white);
			GUI.color = color;
		}

		private void Border(Rect r, Color c, float t)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, t), c);
			Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - t, ((Rect)(ref r)).width, t), c);
			Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c);
			Fill(new Rect(((Rect)(ref r)).xMax - t, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c);
		}

		private void Text(Rect r, string text, Color color, int size, int align)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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)
			_label.fontSize = Mathf.Max(8, size);
			Vector2 val = _label.CalcSize(new GUIContent(text));
			float num = ((Rect)(ref r)).x;
			if (align == 1)
			{
				num = ((Rect)(ref r)).x + (((Rect)(ref r)).width - val.x) / 2f;
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num, ((Rect)(ref r)).y + (((Rect)(ref r)).height - val.y) / 2f, Mathf.Max(((Rect)(ref r)).width, val.x), val.y);
			_label.normal.textColor = new Color(0f, 0f, 0f, 0.9f);
			GUI.Label(new Rect(((Rect)(ref val2)).x + 1f, ((Rect)(ref val2)).y + 1f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height), text, _label);
			_label.normal.textColor = color;
			GUI.Label(val2, text, _label);
		}

		private static void DrawPixelIcon(Texture2D icon, Rect box)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)icon == (Object)null))
			{
				float num = Mathf.Max(1f, Mathf.Floor(Mathf.Min(((Rect)(ref box)).width / (float)((Texture)icon).width, ((Rect)(ref box)).height / (float)((Texture)icon).height)));
				float num2 = (float)((Texture)icon).width * num;
				float num3 = (float)((Texture)icon).height * num;
				GUI.DrawTexture(new Rect(((Rect)(ref box)).x + (((Rect)(ref box)).width - num2) / 2f, ((Rect)(ref box)).y + (((Rect)(ref box)).height - num3) / 2f, num2, num3), (Texture)(object)icon);
			}
		}

		private static bool DrawTk2dSprite(tk2dBaseSprite sprite, Rect box)
		{
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Invalid comparison between Unknown and I4
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: 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_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Invalid comparison between Unknown and I4
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.Collection == (Object)null)
			{
				return false;
			}
			tk2dSpriteDefinition[] spriteDefinitions = sprite.Collection.spriteDefinitions;
			int spriteId = sprite.spriteId;
			if (spriteDefinitions == null || spriteId < 0 || spriteId >= spriteDefinitions.Length)
			{
				return false;
			}
			tk2dSpriteDefinition val = spriteDefinitions[spriteId];
			if (val == null || val.uvs == null || val.uvs.Length < 4)
			{
				return false;
			}
			Material val2 = (((Object)(object)val.materialInst != (Object)null) ? val.materialInst : val.material);
			Texture val3 = (((Object)(object)val2 != (Object)null) ? val2.mainTexture : null);
			if ((Object)(object)val3 == (Object)null)
			{
				return false;
			}
			float num = float.MaxValue;
			float num2 = float.MaxValue;
			float num3 = float.MinValue;
			float num4 = float.MinValue;
			for (int i = 0; i < val.uvs.Length; i++)
			{
				num = Mathf.Min(num, val.uvs[i].x);
				num3 = Mathf.Max(num3, val.uvs[i].x);
				num2 = Mathf.Min(num2, val.uvs[i].y);
				num4 = Mathf.Max(num4, val.uvs[i].y);
			}
			Rect val4 = Rect.MinMaxRect(num, num2, num3, num4);
			float num5 = ((Rect)(ref val4)).width * (float)val3.width;
			float num6 = ((Rect)(ref val4)).height * (float)val3.height;
			if (num5 < 1f || num6 < 1f)
			{
				return false;
			}
			bool flag = (int)val.flipped > 0;
			float num7 = (flag ? num6 : num5);
			float num8 = (flag ? num5 : num6);
			float num9 = Mathf.Min(((Rect)(ref box)).width / num7, ((Rect)(ref box)).height / num8);
			float num10 = ((num9 >= 1f) ? Mathf.Floor(num9) : num9);
			if (num10 <= 0f)
			{
				return false;
			}
			Vector2 center = ((Rect)(ref box)).center;
			Rect val5 = default(Rect);
			((Rect)(ref val5))..ctor(center.x - num5 * num10 / 2f, center.y - num6 * num10 / 2f, num5 * num10, num6 * num10);
			Matrix4x4 matrix = GUI.matrix;
			try
			{
				if (flag)
				{
					GUIUtility.RotateAroundPivot(((int)val.flipped == 2) ? 90f : (-90f), center);
				}
				GUI.DrawTextureWithTexCoords(val5, val3, val4, true);
			}
			finally
			{
				GUI.matrix = matrix;
			}
			return true;
		}

		private void EnsureResources()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_002b: 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_006a: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: 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_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_white == (Object)null)
			{
				_white = new Texture2D(1, 1, (TextureFormat)4, false);
				_white.SetPixel(0, 0, Color.white);
				_white.Apply();
				((Object)_white).hideFlags = (HideFlags)61;
			}
			if (_label == null)
			{
				_label = new GUIStyle(GUI.skin.label);
				_label.wordWrap = false;
			}
			if (!((Object)(object)_heartFull != (Object)null))
			{
				string[] mask = new string[6] { ".##.##.", "#######", "#######", ".#####.", "..###..", "...#..." };
				string[] mask2 = new string[7] { "#######", "#######", "#######", "#######", ".#####.", "..###..", "...#..." };
				string[] mask3 = new string[7] { "..###..", ".#####.", "#######", "#######", "#######", ".#####.", "..###.." };
				string[] mask4 = new string[4] { ".###.....", "##.######", ".###.#.#.", "........." };
				Color red = new Color(0.86f, 0.12f, 0.14f);
				Color grey = new Color(0.22f, 0.2f, 0.24f);
				_heartFull = MakeIcon(mask, (int x, int y) => red, new Color(1f, 0.6f, 0.62f));
				_heartHalf = MakeIcon(mask, (int x, int y) => (x > 3) ? grey : red, new Color(1f, 0.6f, 0.62f));
				_heartEmpty = MakeIcon(mask, (int x, int y) => grey, new Color(0.38f, 0.36f, 0.4f));
				_shield = MakeIcon(mask2, (int x, int y) => new Color(0.3f, 0.62f, 1f), new Color(0.75f, 0.9f, 1f));
				_blank = MakeIcon(mask3, (int x, int y) => new Color(0.35f, 0.75f, 1f), new Color(0.85f, 0.95f, 1f));
				_key = MakeIcon(mask4, (int x, int y) => new Color(0.78f, 0.8f, 0.86f), new Color(1f, 1f, 1f));
				_coin = MakeIcon(mask3, (int x, int y) => new Color(1f, 0.82f, 0.2f), new Color(1f, 0.97f, 0.7f));
			}
		}

		private static Texture2D MakeIcon(string[] mask, PixelColor color, Color highlight)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			int length = mask[0].Length;
			int num = mask.Length;
			Texture2D val = new Texture2D(length, num, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			Color32[] array = (Color32[])(object)new Color32[length * num];
			Color val2 = default(Color);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < length; j++)
				{
					bool num2 = mask[i][j] == '#';
					((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
					if (num2)
					{
						val2 = color(j, i);
						if (j == 0 || i == num - 1 || j == length - 1 || i == 0 || mask[i][j - 1] != '#' || mask[i][j + 1] != '#' || mask[i - 1][j] != '#' || (i + 1 < num && mask[i + 1][j] != '#'))
						{
							val2 = Color.Lerp(val2, Color.black, 0.35f);
						}
						if (j == 1 && i == 1)
						{
							val2 = highlight;
						}
					}
					array[(num - 1 - i) * length + j] = Color32.op_Implicit(val2);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return val;
		}

		private void LogErrorThrottled(string where, Exception e)
		{
			if (!(Time.realtimeSinceStartup < _nextErrorLog))
			{
				_nextErrorLog = Time.realtimeSinceStartup + 10f;
				GungeonTogether.Systems.Logging.Debug.LogWarning("[Hud] " + where + " failed: " + e);
			}
		}
	}
	public static class UIManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static MouseEventHandler <0>__OnMainMenuHostClicked;

			public static FocusEventHandler <1>__OnMainMenuHostFocused;

			public static MouseEventHandler <2>__OnMainMenuJoinClicked;

			public static Action <3>__RefreshServerBrowser;

			public static MouseEventHandler <4>__OnSinglePlayerClicked;

			public static MouseEventHandler <5>__OnServerBrowserRefreshClicked;

			public static MouseEventHandler <6>__OnServerBrowserBackClicked;

			public static MouseEventHandler <7>__OnServerRowClicked;

			public static MouseEventHandler <8>__OnInviteClicked;

			public static MouseEventHandler <9>__OnLeaveClicked;

			public static Action <10>__RefreshPlayerList;
		}

		private static GameObject _root;

		private static dfPanel _panel;

		private static dfLabel _statusLabel;

		private static dfButton _inviteButton;

		private static dfButton _leaveButton;

		private static dfButton _mainMenuHostButton;

		private static dfButton _mainMenuJoinButton;

		private static MainMenuFoyerController _mainMenuController;

		private static dfPanel _serverBrowserPanel;

		private static dfLabel _serverBrowserStatus;

		private static dfButton _serverBrowserRefreshButton;

		private static dfButton _serverBrowserBackButton;

		private static readonly List<dfButton> _serverBrowserRows = new List<dfButton>();

		private static readonly Dictionary<dfButton, ulong> _serverBrowserLobbyIds = new Dictionary<dfButton, ulong>();

		private static bool _serverBrowserOpen;

		private static bool _serverBrowserSubscribed;

		private static bool _singlePlayerHandlerAttached;

		private static bool _launchingHostedGame;

		private static bool _pendingNetworkGameEntry;

		private static float _nextGameEntryAttempt;

		private static float _nextUiErrorLog;

		private static dfPanel _playerListPanel;

		private static dfScrollPanel _playerScrollPanel;

		private static List<dfLabel> _playerLabels = new List<dfLabel>();

		private static bool _subscribed = false;

		public static void Initialise()
		{
		}

		public static void Update()
		{
			try
			{
				GameManager val = Object.FindObjectOfType<GameManager>();
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				EnsureMainMenuHostButton();
				bool doMainMenu = Foyer.DoMainMenu;
				SetMainMenuButtonsVisible(doMainMenu);
				if (doMainMenu)
				{
					SetVisible(visible: false);
					if (NetworkManager.Instance.IsClient)
					{
						_pendingNetworkGameEntry = false;
					}
					TryEnterNetworkGameFromMainMenu();
					return;
				}
				_pendingNetworkGameEntry = false;
				_launchingHostedGame = false;
				if (!val.IsFoyer)
				{
					SetVisible(visible: false);
					return;
				}
				EnsureBuilt();
				bool num = SteamLobbyManager.Instance.IsInLobby || NetworkManager.Instance.IsConnected;
				SetVisible(num);
				if (num)
				{
					UpdateStatus();
					SubscribeEvents();
				}
			}
			catch (Exception ex)
			{
				if (Time.realtimeSinceStartup >= _nextUiErrorLog)
				{
					_nextUiErrorLog = Time.realtimeSinceStartup + 2f;
					GungeonTogether.Systems.Logging.Debug.LogWarning("[UI] Update failed: " + ex);
				}
			}
		}

		private static void EnsureMainMenuHostButton()
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0155: Expected O, but got Unknown
			//IL_01cb: 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_01d6: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Expected O, but got Unknown
			MainMenuFoyerController val = Object.FindObjectOfType<MainMenuFoyerController>();
			if ((Object)(object)val == (Object)null || (Object)(object)val.NewGameButton == (Object)null)
			{
				return;
			}
			if ((Object)(object)_mainMenuController != (Object)(object)val || (Object)(object)_mainMenuHostButton == (Object)null || (Object)(object)_mainMenuJoinButton == (Object)null)
			{
				if ((Object)(object)_mainMenuController != (Object)(object)val)
				{
					_singlePlayerHandlerAttached = false;
					_serverBrowserOpen = false;
				}
				_mainMenuController = val;
				dfControl val2 = ((dfControl)val.NewGameButton).Parent;
				if ((Object)(object)val2 == (Object)null && (Object)(object)((Component)val.NewGameButton).transform.parent != (Object)null)
				{
					val2 = ((Component)((Component)val.NewGameButton).transform.parent).GetComponent<dfControl>();
				}
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				_mainMenuHostButton = CreateButtonFromTemplate(((dfControl)val.NewGameButton).GUIManager, val2, val.NewGameButton, "GT_MainMenuHostButton", "HOST LOBBY", ((dfControl)val.NewGameButton).RelativePosition.x, ((dfControl)val.NewGameButton).RelativePosition.y, ((dfControl)val.NewGameButton).Width, ((dfControl)val.NewGameButton).Height);
				dfButton mainMenuHostButton = _mainMenuHostButton;
				object obj = <>O.<0>__OnMainMenuHostClicked;
				if (obj == null)
				{
					MouseEventHandler val3 = OnMainMenuHostClicked;
					<>O.<0>__OnMainMenuHostClicked = val3;
					obj = (object)val3;
				}
				((dfControl)mainMenuHostButton).Click += (MouseEventHandler)obj;
				dfButton mainMenuHostButton2 = _mainMenuHostButton;
				object obj2 = <>O.<1>__OnMainMenuHostFocused;
				if (obj2 == null)
				{
					FocusEventHandler val4 = OnMainMenuHostFocused;
					<>O.<1>__OnMainMenuHostFocused = val4;
					obj2 = (object)val4;
				}
				((dfControl)mainMenuHostButton2).GotFocus += (FocusEventHandler)obj2;
				_mainMenuJoinButton = CreateButtonFromTemplate(((dfControl)val.NewGameButton).GUIManager, val2, val.NewGameButton, "GT_MainMenuJoinButton", "JOIN LOBBY", ((dfControl)val.NewGameButton).RelativePosition.x, ((dfControl)val.NewGameButton).RelativePosition.y, ((dfControl)val.NewGameButton).Width, ((dfControl)val.NewGameButton).Height);
				dfButton mainMenuJoinButton = _mainMenuJoinButton;
				object obj3 = <>O.<2>__OnMainMenuJoinClicked;
				if (obj3 == null)
				{
					MouseEventHandler val5 = OnMainMenuJoinClicked;
					<>O.<2>__OnMainMenuJoinClicked = val5;
					obj3 = (object)val5;
				}
				((dfControl)mainMenuJoinButton).Click += (MouseEventHandler)obj3;
				dfButton mainMenuJoinButton2 = _mainMenuJoinButton;
				object obj4 = <>O.<1>__OnMainMenuHostFocused;
				if (obj4 == null)
				{
					FocusEventHandler val6 = OnMainMenuHostFocused;
					<>O.<1>__OnMainMenuHostFocused = val6;
					obj4 = (object)val6;
				}
				((dfControl)mainMenuJoinButton2).GotFocus += (FocusEventHandler)obj4;
				UIKeyControls obj5 = ((Component)_mainMenuHostButton).gameObject.AddComponent<UIKeyControls>();
				obj5.selectOnAction = true;
				obj5.clearRepeatingOnSelect = true;
				UIKeyControls obj6 = ((Component)_mainMenuJoinButton).gameObject.AddComponent<UIKeyControls>();
				obj6.selectOnAction = true;
				obj6.clearRepeatingOnSelect = true;
				EnsureServerBrowser(val2, val.NewGameButton);
				if (!_serverBrowserSubscribed)
				{
					SteamLobbyManager.Instance.OnLobbySearchUpdated += RefreshServerBrowser;
					_serverBrowserSubscribed = true;
				}
				if (!_singlePlayerHandlerAttached)
				{
					dfButton newGameButton = val.NewGameButton;
					object obj7 = <>O.<4>__OnSinglePlayerClicked;
					if (obj7 == null)
					{
						MouseEventHandler val7 = OnSinglePlayerClicked;
						<>O.<4>__OnSinglePlayerClicked = val7;
						obj7 = (object)val7;
					}
					((dfControl)newGameButton).Click += (MouseEventHandler)obj7;
					_singlePlayerHandlerAttached = true;
				}
				GungeonTogether.Systems.Logging.Debug.Log("[UI] Main-menu HOST/JOIN LOBBY buttons created.");
			}
			LayoutMainMenuButtons(val);
			((dfControl)_mainMenuHostButton).IsEnabled = !NetworkManager.Instance.IsConnected && !SteamLobbyManager.Instance.IsInLobby;
			((dfControl)_mainMenuJoinButton).IsEnabled = !NetworkManager.Instance.IsConnected && !SteamLobbyManager.Instance.IsInLobby;
		}

		private static void LayoutMainMenuButtons(MainMenuFoyerController mm)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_mainMenuHostButton == (Object)null || (Object)(object)mm.QuitGameButton == (Object)null)
			{
				return;
			}
			float x = ((dfControl)mm.QuitGameButton).RelativePosition.x;
			float y = ((dfControl)mm.QuitGameButton).RelativePosition.y;
			((dfControl)mm.ContinueGameButton).RelativePosition = Vector3Extensions.WithY(Vector3Extensions.WithX(((dfControl)mm.ContinueGameButton).RelativePosition, x), y - 255f);
			((dfControl)mm.NewGameButton).RelativePosition = Vector3Extensions.WithY(Vector3Extensions.WithX(((dfControl)mm.NewGameButton).RelativePosition, x), y - 204f);
			((dfControl)_mainMenuHostButton).RelativePosition = Vector3Extensions.WithY(Vector3Extensions.WithX(((dfControl)_mainMenuHostButton).RelativePosition, x), y - 153f);
			((dfControl)_mainMenuJoinButton).RelativePosition = Vector3Extensions.WithY(Vector3Extensions.WithX(((dfControl)_mainMenuJoinButton).RelativePosition, x), y - 102f);
			((dfControl)mm.ControlsButton).RelativePosition = Vector3Extensions.WithY(Vector3Extensions.WithX(((dfControl)mm.ControlsButton).RelativePosition, x), y - 51f);
			List<dfButton> list = new List<dfButton>();
			if (((dfControl)mm.ContinueGameButton).IsEnabled && ((dfControl)mm.ContinueGameButton).IsVisible)
			{
				list.Add(mm.ContinueGameButton);
			}
			list.Add(mm.NewGameButton);
			list.Add(_mainMenuHostButton);
			list.Add(_mainMenuJoinButton);
			list.Add(mm.ControlsButton);
			list.Add(mm.QuitGameButton);
			for (int i = 0; i < list.Count; i++)
			{
				dfButton val = list[i];
				dfButton up = list[(i + list.Count - 1) % list.Count];
				dfButton down = list[(i + 1) % list.Count];
				UIKeyControls val2 = ((Component)val).GetComponent<UIKeyControls>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).gameObject.AddComponent<UIKeyControls>();
				}
				val2.up = (dfControl)(object)up;
				val2.down = (dfControl)(object)down;
			}
			if (_serverBrowserOpen)
			{
				ConfigureServerBrowserNavigation();
			}
		}

		private static void SetMainMenuButtonsVisible(bool visible)
		{
			if ((Object)(object)_mainMenuHostButton != (Object)null)
			{
				((dfControl)_mainMenuHostButton).IsVisible = visible;
				((dfControl)_mainMenuHostButton).IsInteractive = visible;
			}
			if ((Object)(object)_mainMenuJoinButton != (Object)null)
			{
				((dfControl)_mainMenuJoinButton).IsVisible = visible;
				((dfControl)_mainMenuJoinButton).IsInteractive = visible;
			}
			if ((Object)(object)_serverBrowserPanel != (Object)null)
			{
				((dfControl)_serverBrowserPanel).IsVisible = visible && _serverBrowserOpen;
			}
		}

		private static void EnsureServerBrowser(dfControl parent, dfButton template)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Expected O, but got Unknown
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			if (!((Object)(object)_serverBrowserPanel != (Object)null))
			{
				GameObject val = new GameObject("GT_ServerBrowserPanel");
				val.transform.parent = ((Component)parent).transform;
				val.transform.localScale = Vector3.one;
				_serverBrowserPanel = val.AddComponent<dfPanel>();
				parent.AddControl((dfControl)(object)_serverBrowserPanel);
				_serverBrowserPanel.Atlas = ((dfInteractiveBase)template).Atlas;
				_serverBrowserPanel.BackgroundSprite = "blank";
				((dfControl)_serverBrowserPanel).Color = new Color32((byte)0, (byte)0, (byte)0, (byte)220);
				((dfControl)_serverBrowserPanel).Width = 560f;
				((dfControl)_serverBrowserPanel).Height = 390f;
				((dfControl)_serverBrowserPanel).RelativePosition = new Vector3(((dfControl)template).RelativePosition.x + ((dfControl)template).Width + 45f, ((dfControl)template).RelativePosition.y - 50f, 0f);
				((dfControl)_serverBrowserPanel).IsVisible = false;
				dfLabel obj = CreateLabel(((dfControl)template).GUIManager, (dfControl)(object)_serverBrowserPanel, template);
				obj.Text = "GUNGEON TOGETHER LOBBIES";
				((dfControl)obj).RelativePosition = new Vector3(15f, 12f, 0f);
				((dfControl)obj).Width = 530f;
				((dfControl)obj).Height = 35f;
				obj.TextScale = 1.1f;
				_serverBrowserStatus = CreateLabel(((dfControl)template).GUIManager, (dfControl)(object)_serverBrowserPanel, template);
				((dfControl)_serverBrowserStatus).RelativePosition = new Vector3(15f, 49f, 0f);
				((dfControl)_serverBrowserStatus).Width = 530f;
				((dfControl)_serverBrowserStatus).Height = 28f;
				_serverBrowserStatus.TextScale = 0.8f;
				_serverBrowserRefreshButton = CreateButtonFromTemplate(((dfControl)template).GUIManager, (dfControl)(object)_serverBrowserPanel, template, "GT_ServerRefresh", "REFRESH", 15f, 335f, 255f, 40f);
				_serverBrowserBackButton = CreateButtonFromTemplate(((dfControl)template).GUIManager, (dfControl)(object)_serverBrowserPanel, template, "GT_ServerBack", "BACK", 290f, 335f, 255f, 40f);
				dfButton serverBrowserRefreshButton = _serverBrowserRefreshButton;
				object obj2 = <>O.<5>__OnServerBrowserRefreshClicked;
				if (obj2 == null)
				{
					MouseEventHandler val2 = OnServerBrowserRefreshClicked;
					<>O.<5>__OnServerBrowserRefreshClicked = val2;
					obj2 = (object)val2;
				}
				((dfControl)serverBrowserRefreshButton).Click += (MouseEventHandler)obj2;
				dfButton serverBrowserBackButton = _serverBrowserBackButton;
				object obj3 = <>O.<6>__OnServerBrowserBackClicked;
				if (obj3 == null)
				{
					MouseEventHandler val3 = OnServerBrowserBackClicked;
					<>O.<6>__OnServerBrowserBackClicked = val3;
					obj3 = (object)val3;
				}
				((dfControl)serverBrowserBackButton).Click += (MouseEventHandler)obj3;
			}
		}

		private static void RefreshServerBrowser()
		{
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			if ((Object)(object)_serverBrowserPanel == (Object)null)
			{
				return;
			}
			foreach (dfButton serverBrowserRow in _serverBrowserRows)
			{
				if ((Object)(object)serverBrowserRow != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)serverBrowserRow).gameObject);
				}
			}
			_serverBrowserRows.Clear();
			_serverBrowserLobbyIds.Clear();
			SteamLobbyManager instance = SteamLobbyManager.Instance;
			_serverBrowserStatus.Text = instance.LobbySearchStatus;
			int num = Mathf.Min(5, instance.DiscoveredLobbies.Count);
			for (int i = 0; i < num; i++)
			{
				DiscoveredLobby discoveredLobby = instance.DiscoveredLobbies[i];
				string text = (string.IsNullOrEmpty(discoveredLobby.ModVersion) ? "unknown" : discoveredLobby.ModVersion);
				string text2 = (discoveredLobby.IsCompatible ? "" : ("  [INCOMPATIBLE v" + text + "]"));
				string text3 = discoveredLobby.HostName + "   " + discoveredLobby.CurrentPlayers + "/" + discoveredLobby.MaxPlayers + text2;
				dfButton val = CreateButtonFromTemplate(((dfControl)_mainMenuHostButton).GUIManager, (dfControl)(object)_serverBrowserPanel, _mainMenuHostButton, "GT_ServerRow_" + i, text3, 15f, 82f + (float)i * 49f, 530f, 42f);
				((dfControl)val).IsEnabled = discoveredLobby.IsCompatible && discoveredLobby.CurrentPlayers < discoveredLobby.MaxPlayers;
				object obj = <>O.<7>__OnServerRowClicked;
				if (obj == null)
				{
					MouseEventHandler val2 = OnServerRowClicked;
					<>O.<7>__OnServerRowClicked = val2;
					obj = (object)val2;
				}
				((dfControl)val).Click += (MouseEventHandler)obj;
				_serverBrowserRows.Add(val);
				_serverBrowserLobbyIds[val] = discoveredLobby.LobbyId;
			}
			ConfigureServerBrowserNavigation();
		}

		private static void ConfigureServerBrowserNavigation()
		{
			List<dfButton> list = new List<dfButton>();
			foreach (dfButton serverBrowserRow in _serverBrowserRows)
			{
				if ((Object)(object)serverBrowserRow != (Object)null && ((dfControl)serverBrowserRow).IsEnabled)
				{
					list.Add(serverBrowserRow);
				}
			}
			if ((Object)(object)_serverBrowserRefreshButton != (Object)null)
			{
				list.Add(_serverBrowserRefreshButton);
			}
			if ((Object)(object)_serverBrowserBackButton != (Object)null)
			{
				list.Add(_serverBrowserBackButton);
			}
			if (list.Count == 0)
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				dfButton val = list[i];
				UIKeyControls val2 = ((Component)val).GetComponent<UIKeyControls>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).gameObject.AddComponent<UIKeyControls>();
				}
				val2.selectOnAction = true;
				val2.clearRepeatingOnSelect = true;
				val2.up = (dfControl)(object)((i == 0) ? _mainMenuJoinButton : list[i - 1]);
				val2.down = (dfControl)(object)((i == list.Count - 1) ? _mainMenuJoinButton : list[i + 1]);
			}
			UIKeyControls component = ((Component)_mainMenuJoinButton).GetComponent<UIKeyControls>();
			if ((Object)(object)component != (Object)null)
			{
				component.down = (dfControl)(object)list[0];
			}
		}

		private static void EnsureBuilt()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Expected O, but got Unknown
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Expected O, but got Unknown
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel != (Object)null)
			{
				return;
			}
			GameUIRoot val = Object.FindObjectOfType<GameUIRoot>();
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Manager == (Object)null))
			{
				dfGUIManager manager = val.Manager;
				dfButton val2 = null;
				MainMenuFoyerController val3 = Object.FindObjectOfType<MainMenuFoyerController>();
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3.NewGameButton != (Object)null)
				{
					val2 = val3.NewGameButton;
				}
				if ((Object)(object)val2 == (Object)null)
				{
					GungeonTogether.Systems.Logging.Debug.LogWarning("[UI] Could not find MainMenuFoyerController.NewGameButton as template.");
				}
				_root = new GameObject("GungeonTogether_UI");
				_root.transform.parent = ((Component)manager).transform;
				_root.transform.localPosition = Vector3.zero;
				_root.transform.localScale = Vector3.one;
				_panel = _root.AddComponent<dfPanel>();
				if ((Object)(object)manager != (Object)null)
				{
					manager.AddControl((dfControl)(object)_panel);
				}
				((dfControl)_panel).Anchor = (dfAnchorStyle)5;
				((dfControl)_panel).RelativePosition = new Vector3(25f, 25f, 0f);
				((dfControl)_panel).Width = 420f;
				((dfControl)_panel).Height = 300f;
				((dfControl)_panel).IsVisible = true;
				((dfControl)_panel).Opacity = 1f;
				GungeonTogether.Systems.Logging.Debug.Log($"[UI] Panel created: Position={((dfControl)_panel).RelativePosition}, Size={((dfControl)_panel).Width}x{((dfControl)_panel).Height}");
				if ((Object)(object)val2 != (Object)null)
				{
					_panel.Atlas = ((dfInteractiveBase)val2).Atlas;
					GungeonTogether.Systems.Logging.Debug.Log("[UI] Panel atlas set from template");
				}
				_statusLabel = CreateLabel(manager, (dfControl)(object)_panel, val2);
				((dfControl)_statusLabel).RelativePosition = new Vector3(10f, 10f, 0f);
				((dfControl)_statusLabel).Width = ((dfControl)_panel).Width - 20f;
				((dfControl)_statusLabel).Height = 70f;
				_statusLabel.VerticalAlignment = (dfVerticalAlignment)0;
				_statusLabel.TextScale = 1f;
				_statusLabel.ProcessMarkup = true;
				_statusLabel.ColorizeSymbols = true;
				GungeonTogether.Systems.Logging.Debug.Log($"[UI] Status label created: Position={((dfControl)_statusLabel).RelativePosition}, Size={((dfControl)_statusLabel).Width}x{((dfControl)_statusLabel).Height}");
				float num = ((dfControl)_statusLabel).RelativePosition.y + ((dfControl)_statusLabel).Height + 10f;
				float num2 = (((dfControl)_panel).Width - 30f) / 2f;
				float num3 = 40f;
				float num4 = 10f;
				GungeonTogether.Systems.Logging.Debug.Log($"[UI] Button layout: currentY={num}, buttonWidth={num2}, buttonHeight={num3}, spacing={num4}");
				_inviteButton = CreateButtonFromTemplate(manager, (dfControl)(object)_panel, val2, "GT_InviteButton", "INVITE", 10f, num, num2, num3);
				dfButton inviteButton = _inviteButton;
				object obj = <>O.<8>__OnInviteClicked;
				if (obj == null)
				{
					MouseEventHandler val4 = OnInviteClicked;
					<>O.<8>__OnInviteClicked = val4;
					obj = (object)val4;
				}
				((dfControl)inviteButton).Click += (MouseEventHandler)obj;
				GungeonTogether.Systems.Logging.Debug.Log($"[UI] Invite button created: Position={((dfControl)_inviteButton).RelativePosition}, Size={((dfControl)_inviteButton).Width}x{((dfControl)_inviteButton).Height}, Visible={((dfControl)_inviteButton).IsVisible}");
				_leaveButton = CreateButtonFromTemplate(manager, (dfControl)(object)_panel, val2, "GT_LeaveButton", "LEAVE", 10f + num2 + num4, num, num2, num3);
				dfButton leaveButton = _leaveButton;
				object obj2 = <>O.<9>__OnLeaveClicked;
				if (obj2 == null)
				{
					MouseEventHandler val5 = OnLeaveClicked;
					<>O.<9>__OnLeaveClicked = val5;
					obj2 = (object)val5;
				}
				((dfControl)leaveButton).Click += (MouseEventHandler)obj2;
				GameObject val6 = new GameObject("GT_PlayerListPanel");
				val6.transform.parent = ((Component)_panel).transform;
				val6.transform.localScale = Vector3.one;
				_playerListPanel = val6.AddComponent<dfPanel>();
				((dfControl)_panel).AddControl((dfControl)(object)_playerListPanel);
				((dfControl)_playerListPanel).RelativePosition = new Vector3(10f, 130f, 0f);
				((dfControl)_playerListPanel).Width = ((dfControl)_panel).Width - 20f;
				((dfControl)_playerListPanel).Height = 120f;
				_playerListPanel.Atlas = (((Object)(object)val2 != (Object)null) ? ((dfInteractiveBase)val2).Atlas : null);
				_playerListPanel.BackgroundSprite = "blank";
				((dfControl)_playerListPanel).Color = new Color32((byte)0, (byte)0, (byte)0, (byte)150);
				GameObject val7 = new GameObject("GT_PlayerScrollPanel");
				val7.transform.parent = ((Component)_playerListPanel).transform;
				val7.transform.localScale = Vector3.one;
				_playerScrollPanel = val7.AddComponent<dfScrollPanel>();
				((dfControl)_playerListPanel).AddControl((dfControl)(object)_playerScrollPanel);
				((dfControl)_playerScrollPanel).RelativePosition = Vector3.zero;
				((dfControl)_playerScrollPanel).Width = ((dfControl)_playerListPanel).Width;
				((dfControl)_playerScrollPanel).Height = ((dfControl)_playerListPanel).Height;
			}
		}

		private static void SubscribeEvents()
		{
			if (!_subscribed)
			{
				SteamLobbyManager.Instance.OnPlayerListChanged += RefreshPlayerList;
				_subscribed = true;
				RefreshPlayerList();
			}
		}

		private static void RefreshPlayerList()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_playerScrollPanel == (Object)null)
			{
				return;
			}
			foreach (dfLabel playerLabel in _playerLabels)
			{
				Object.Destroy((Object)(object)((Component)playerLabel).gameObject);
			}
			_playerLabels.Clear();
			List<ulong> lobbyMembers = SteamLobbyManager.Instance.GetLobbyMembers();
			float num = 0f;
			float num2 = 20f;
			foreach (ulong item in lobbyMembers)
			{
				string playerName = SteamReflectionHelper.GetPlayerName(item);
				dfLabel val = CreateLabel(null, (dfControl)(object)_playerScrollPanel, null);
				bool gameConnected;
				string memberNetworkState = GetMemberNetworkState(item, out gameConnected);
				val.Text = playerName + "  " + memberNetworkState;
				((dfControl)val).RelativePosition = new Vector3(5f, num, 0f);
				((dfControl)val).Width = ((dfControl)_playerScrollPanel).Width - 10f;
				((dfControl)val).Height = num2;
				val.TextScale = 0.8f;
				((dfControl)val).Color = Color32.op_Implicit((Color)(gameConnected ? Color.green : new Color(1f, 0.75f, 0.25f)));
				val.VerticalAlignment = (dfVerticalAlignment)1;
				_playerLabels.Add(val);
				num += num2 + 2f;
			}
		}

		public static void NotifyNetworkStatusChanged()
		{
			RefreshPlayerList();
		}

		private static string GetMemberNetworkState(ulong id, out bool gameConnected)
		{
			NetworkManager instance = NetworkManager.Instance;
			ulong localSteamId = SteamReflectionHelper.GetLocalSteamId();
			if (instance.IsHost && instance.Host != null)
			{
				if (id == localSteamId)
				{
					gameConnected = true;
					return "[HOST]";
				}
				gameConnected = instance.Host.GetConnectedClientIds().Contains(id);
				if (!gameConnected)
				{
					return "[STEAM LOBBY ONLY]";
				}
				return "[GAME CONNECTED]";
			}
			if (instance.IsClient && instance.Client != null)
			{
				if (id == localSteamId)
				{
					gameConnected = instance.Client.IsConnected;
					if (!gameConnected)
					{
						return "[YOU: LOBBY ONLY]";
					}
					return "[YOU: CONNECTED]";
				}
				if (id == instance.Client.HostId)
				{
					gameConnected = instance.Client.IsConnected;
					if (!gameConnected)
					{
						return "[HOST: NOT CONNECTED]";
					}
					return "[HOST: CONNECTED]";
				}
				gameConnected = (Object)(object)PlayerManager.Instance.GetRemotePlayerController(id) != (Object)null;
				if (!gameConnected)
				{
					return "[STEAM LOBBY ONLY]";
				}
				return "[GAME CONNECTED]";
			}
			gameConnected = false;
			return "[STEAM LOBBY ONLY]";
		}

		private static void UpdateStatus()
		{
			if (!((Object)(object)_statusLabel == (Object)null))
			{
				SteamLobbyManager instance = SteamLobbyManager.Instance;
				string text = (instance.IsInLobby ? ("Lobby: " + instance.CurrentLobbyId) : "Lobby: (none)");
				string text2 = (NetworkManager.Instance.IsHost ? "Role: Host" : (NetworkManager.Instance.IsClient ? "Role: Client" : "Role: (none)"));
				NetworkManager instance2 = NetworkManager.Instance;
				string text3 = ((instance2.IsHost && instance2.Host != null) ? ("Net: Hosting v" + 21 + " (" + (instance2.Host.GetConnectedClientIds().Count + 1) + "/" + 3 + ")") : ((instance2.IsClient && instance2.Client != null && instance2.Client.IsConnected) ? ("Net: Connected (protocol " + 21 + ")") : ((instance2.IsClient && instance2.Client != null && instance2.Client.IsConnecting) ? "Net: Connecting..." : ((!instance2.IsClient || instance2.Client == null || string.IsNullOrEmpty(instance2.Client.LastConnectionError)) ? "Net: Disconnected" : ("Net: REJECTED - " + instance2.Client.LastConnectionError)))));
				_statusLabel.ModifyLocalizedText("GUNGEON TOGETHER\n" + text + "\n" + text2 + " | " + text3);
				if ((Object)(object)_inviteButton != (Object)null)
				{
					((dfControl)_inviteButton).IsEnabled = instance.IsInLobby;
				}
				if ((Object)(object)_leaveButton != (Object)null)
				{
					((dfControl)_leaveButton).IsEnabled = instance.IsInLobby || NetworkManager.Instance.IsConnected;
				}
			}
		}

		private static void SetVisible(bool visible)
		{
			if ((Object)(object)_panel != (Object)null)
			{
				((dfControl)_panel).IsVisible = visible;
			}
		}

		private static void OnMainMenuHostClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			if (!((Object)(object)_mainMenuController == (Object)null) && !NetworkManager.Instance.IsConnected && !SteamLobbyManager.Instance.IsInLobby)
			{
				GungeonTogether.Systems.Logging.Debug.Log("[UI] Main-menu Host Lobby clicked.");
				_pendingNetworkGameEntry = true;
				SteamLobbyManager.Instance.CreateLobby();
			}
		}

		private static void OnMainMenuJoinClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			if (!NetworkManager.Instance.IsConnected && !SteamLobbyManager.Instance.IsInLobby)
			{
				_serverBrowserOpen = true;
				if ((Object)(object)_serverBrowserPanel != (Object)null)
				{
					((dfControl)_serverBrowserPanel).IsVisible = true;
				}
				SteamLobbyManager.Instance.RequestLobbyList();
			}
		}

		private static void OnServerBrowserRefreshClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			SteamLobbyManager.Instance.RequestLobbyList();
		}

		private static void OnServerBrowserBackClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			_serverBrowserOpen = false;
			if ((Object)(object)_serverBrowserPanel != (Object)null)
			{
				((dfControl)_serverBrowserPanel).IsVisible = false;
			}
		}

		private static void OnServerRowClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			dfButton val = (dfButton)(object)((control is dfButton) ? control : null);
			if (!((Object)(object)val == (Object)null) && _serverBrowserLobbyIds.TryGetValue(val, out var value) && value != 0L)
			{
				_serverBrowserOpen = false;
				if ((Object)(object)_serverBrowserPanel != (Object)null)
				{
					((dfControl)_serverBrowserPanel).IsVisible = false;
				}
				_pendingNetworkGameEntry = false;
				SteamLobbyManager.Instance.JoinLobby(value);
			}
		}

		private static void OnSinglePlayerClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			_serverBrowserOpen = false;
			if ((Object)(object)_serverBrowserPanel != (Object)null)
			{
				((dfControl)_serverBrowserPanel).IsVisible = false;
			}
			if (_launchingHostedGame)
			{
				_launchingHostedGame = false;
				return;
			}
			if (SteamLobbyManager.Instance.IsInLobby)
			{
				SteamLobbyManager.Instance.LeaveLobby();
			}
			if (NetworkManager.Instance.CurrentRole != null)
			{
				NetworkManager.Instance.Shutdown();
			}
		}

		private static void TryEnterNetworkGameFromMainMenu()
		{
			if (_pendingNetworkGameEntry && !((Object)(object)_mainMenuController == (Object)null) && !_launchingHostedGame && NetworkManager.Instance.IsHost && SteamLobbyManager.Instance.IsInLobby && NetworkManager.Instance.IsConnected && !(Time.realtimeSinceStartup < _nextGameEntryAttempt))
			{
				_nextGameEntryAttempt = Time.realtimeSinceStartup + 0.75f;
				GungeonTogether.Systems.Logging.Debug.Log("[UI] Entering the foyer for the network lobby.");
				_launchingHostedGame = true;
				((dfControl)_mainMenuController.NewGameButton).DoClick();
				_launchingHostedGame = false;
			}
		}

		public static void EnterClientFoyerFromWorldState()
		{
			if (Foyer.DoMainMenu && !((Object)(object)_mainMenuController == (Object)null) && !_launchingHostedGame)
			{
				GungeonTogether.Systems.Logging.Debug.Log("[UI] Entering the foyer from the host's authoritative world state.");
				_launchingHostedGame = true;
				((dfControl)_mainMenuController.NewGameButton).DoClick();
				_launchingHostedGame = false;
			}
		}

		private static void OnMainMenuHostFocused(dfControl control, dfFocusEventArgs args)
		{
			if (Foyer.DoMainMenu && (Object)(object)GameManager.Instance != (Object)null)
			{
				AkSoundEngine.PostEvent("Play_UI_menu_select_01", ((Component)GameManager.Instance).gameObject);
			}
		}

		private static void OnInviteClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			GungeonTogether.Systems.Logging.Debug.Log("[UI] Invite clicked.");
			SteamLobbyManager.Instance.OpenInviteDialog();
		}

		private static void OnLeaveClicked(dfControl control, dfMouseEventArgs mouseEvent)
		{
			GungeonTogether.Systems.Logging.Debug.Log("[UI] Leave clicked.");
			SteamLobbyManager.Instance.LeaveLobby();
			NetworkManager.Instance.Shutdown();
			_pendingNetworkGameEntry = false;
			_launchingHostedGame = false;
			SetVisible(visible: false);
			if ((Object)(object)GameManager.Instance != (Object)null)
			{
				GameManager.Instance.LoadMainMenu();
			}
		}

		private static dfLabel CreateLabel(dfGUIManager gui, dfControl parent, dfButton template)
		{
			//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_0027: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("GT_StatusLabel");
			val.transform.parent = (((Object)(object)parent != (Object)null) ? ((Component)parent).transform : null);
			val.transform.localScale = Vector3.one;
			dfLabel val2 = val.AddComponent<dfLabel>();
			if ((Object)(object)parent != (Object)null)
			{
				parent.AddControl((dfControl)(object)val2);
			}
			if ((Object)(object)template != (Object)null)
			{
				val2.Atlas = ((dfInteractiveBase)template).Atlas;
				val2.Font = template.Font;
				val2.TextScale = template.TextScale;
				((dfControl)val2).Color = template.TextColor;
			}
			else
			{
				((dfControl)val2).Color = Color32.op_Implicit(Color.white);
			}
			val2.WordWrap = true;
			((dfControl)val2).IsVisible = true;
			return val2;
		}

		private static dfButton CreateButtonFromTemplate(dfGUIManager gui, dfControl parent, dfButton template, string name, string text, float posX, float posY, float width, float height)
		{
			//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_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0128: 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)
			GameObject val = new GameObject(name);
			val.transform.parent = (((Object)(object)parent != (Object)null) ? ((Component)parent).transform : null);
			val.transform.localScale = Vector3.one;
			val.transform.localPosition = Vector3.zero;
			dfButton val2 = val.AddComponent<dfButton>();
			if ((Object)(object)parent != (Object)null)
			{
				parent.AddControl((dfControl)(object)val2);
			}
			if ((Object)(object)template != (Object)null)
			{
				((dfInteractiveBase)val2).Atlas = ((dfInteractiveBase)template).Atlas;
				val2.Font = template.Font;
				val2.TextScale = template.TextScale;
				val2.TextColor = template.TextColor;
				((dfInteractiveBase)val2).BackgroundSprite = ((dfInteractiveBase)template).BackgroundSprite;
				((dfInteractiveBase)val2).FocusSprite = ((dfInteractiveBase)template).FocusSprite;
				((dfInteractiveBase)val2).HoverSprite = ((dfInteractiveBase)template).HoverSprite;
				val2.PressedSprite = template.PressedSprite;
				((dfInteractiveBase)val2).DisabledSprite = ((dfInteractiveBase)template).DisabledSprite;
			}
			val2.Text = text;
			val2.forceUpperCase = true;
			((dfControl)val2).IsInteractive = true;
			((dfControl)val2).IsVisible = true;
			((dfControl)val2).IsEnabled = true;
			((dfControl)val2).RelativePosition = new Vector3(posX, posY, 0f);
			((dfControl)val2).Width = width;
			((dfControl)val2).Height = height;
			GungeonTogether.Systems.Logging.Debug.Log($"[UI] Button '{name}' created from scratch: Position={((dfControl)val2).RelativePosition}, Size={((dfControl)val2).Width}x{((dfControl)val2).Height}");
			return val2;
		}
	}
}
namespace GungeonTogether.Systems.Logging
{
	public static class Debug
	{
		public static void Log(object message)
		{
			Logger.LogDebug(message);
		}

		public static void Info(object message)
		{
			Logger.LogInfo(message);
		}

		public static void LogWarning(object message)
		{
			Logger.LogWarning(message);
		}

		public static void LogError(object message)
		{
			Logger.LogError(message);
		}
	}
	public static class Logger
	{
		private static ManualLogSource _logSource;

		public static void Initialise(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		public static void LogInfo(object data)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogInfo(data);
			}
		}

		public static void LogWarning(object data)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogWarning(data);
			}
		}

		public static void LogError(object data)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogError(data);
			}
		}

		public static void LogDebug(object data)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogDebug(data);
			}
		}
	}
}
namespace GungeonTogether.Networking
{
	public class ClientController : IClient, INetworkRole
	{
		private ulong _hostId;

		private SteamP2PManager _p2p;

		private float _nextPositionSendTime;

		private const float PositionSendInterval = 0.033f;

		private bool _connectPending;

		private float _connectRetryTimer;

		private const float ConnectRetryInterval = 1f;

		public bool IsConnected { get; private set; }

		public bool IsConnecting => _connectPending;

		public string LastConnectionError { get; private set; } = "";

		public ulong HostId => _hostId;

		public void Initialise()
		{
			_p2p = SteamP2PManager.Instance;
			GungeonTogether.Systems.Logging.Debug.Log("ClientController Initialised.");
		}

		public void Connect(ulong hostId)
		{
			_hostId = hostId;
			IsConnected = false;
			_connectPending = true;
			LastConnectionError = "";
			_connectRetryTimer = 0f;
			UIManager.NotifyNetworkStatusChanged();
			GungeonTogether.Systems.Logging.Debug.Log($"[Client] Connect called to {hostId}, sending initial connection request...");
		}

		public void Update()
		{
			if (_connectPending && Time.realtimeSinceStartup >= _connectRetryTimer)
			{
				_connectRetryTimer = Time.realtimeSinceStartup + 1f;
				GungeonTogether.Systems.Logging.Debug.Log($"Sending connection request to {_hostId}...");
				SendPacket(_hostId, new ConnectionRequestPacket
				{
					ClientId = _p2p.LocalSteamID,
					ProtocolVersion = 21,
					ModManifest = ModCompatibility.GetManifest()
				});
			}
			if (!IsConnected || !WorldSyncManager.Instance.IsClientWorldReady || Time.realtimeSinceStartup < _nextPositionSendTime)
			{
				return;
			}
			_nextPositionSendTime = Time.realtimeSinceStartup + 0.033f;
			ulong num = ((_p2p.LocalSteamID != 0L) ? _p2p.LocalSteamID : SteamReflectionHelper.GetLocalSteamId());
			if (num != 0L)
			{
				PlayerPositionPacket playerPositionPacket = PlayerManager.Instance.CreateLocalPositionPacket(num);
				if (playerPositionPacket != null)
				{
					SendPacket(_hostId, playerPositionPacket, reliable: false);
				}
			}
		}

		public void HandleConnectionAccepted(ulong senderId, ConnectionAcceptedPacket packet)
		{
			if (senderId != _hostId)
			{
				return;
			}
			if (packet.ProtocolVersion != 21)
			{
				GungeonTogether.Systems.Logging.Debug.LogWarning($"[Client] Protocol mismatch. Host={packet.ProtocolVersion} Local={21}");
				Disconnect();
				return;
			}
			bool num = !