Decompiled source of GungeonTogether 3Player v0.10.8
BepInEx/plugins/GungeonTogether.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
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 = !