using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Steamworks;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LobbyFriends")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LobbyFriends")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6400d1ff-9761-481e-9295-48b6c15e0824")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LobbyFriends;
[BepInPlugin("com.magearena.lobbyfriends", "LobbyFriends", "1.0.0")]
[BepInProcess("MageArena.exe")]
public class LobbyFriends : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <MonitorLobbyState>d__14 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LobbyFriends <>4__this;
private ulong <previousLobbyID>5__1;
private bool <wasInLobby>5__2;
private bool <wasInGame>5__3;
private bool <wasInScoreboard>5__4;
private ulong <currentLobbyID>5__5;
private bool <currentlyInLobby>5__6;
private MainMenuManager <mainMenuManager>5__7;
private bool <inLobbyUI>5__8;
private bool <inGame>5__9;
private bool <inScoreboard>5__10;
private bool <shouldBeInLobby>5__11;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MonitorLobbyState>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<mainMenuManager>5__7 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_032e: Unknown result type (might be due to invalid IL or missing references)
//IL_0338: Expected O, but got Unknown
//IL_0236: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Expected O, but got Unknown
//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0300: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<previousLobbyID>5__1 = 0uL;
<wasInLobby>5__2 = false;
<wasInGame>5__3 = false;
<wasInScoreboard>5__4 = false;
goto IL_0350;
case 1:
<>1__state = -1;
((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.MonitorPlayers());
break;
case 2:
<>1__state = -1;
((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.MonitorPlayers());
break;
case 3:
{
<>1__state = -1;
<mainMenuManager>5__7 = null;
goto IL_0350;
}
IL_0350:
<currentLobbyID>5__5 = BootstrapManager.CurrentLobbyID;
<currentlyInLobby>5__6 = <currentLobbyID>5__5 != 0;
<mainMenuManager>5__7 = Object.FindFirstObjectByType<MainMenuManager>();
<inLobbyUI>5__8 = (Object)(object)<mainMenuManager>5__7 != (Object)null && !<mainMenuManager>5__7.GameHasStarted;
<inGame>5__9 = (Object)(object)<mainMenuManager>5__7 != (Object)null && <mainMenuManager>5__7.GameHasStarted;
<inScoreboard>5__10 = <>4__this.CheckForScoreboard();
<shouldBeInLobby>5__11 = <currentlyInLobby>5__6 | <inLobbyUI>5__8;
if (<inGame>5__9 && !<wasInGame>5__3)
{
<wasInGame>5__3 = true;
<wasInLobby>5__2 = false;
<wasInScoreboard>5__4 = false;
<>4__this.isInLobby = false;
<>4__this.gameStarted = true;
<>4__this.ClearPlayerList();
}
else if (!<inGame>5__9 & <wasInGame>5__3)
{
<wasInGame>5__3 = false;
<>4__this.gameStarted = false;
if (!<inScoreboard>5__10)
{
<wasInLobby>5__2 = false;
}
}
if (<inScoreboard>5__10 && !<wasInScoreboard>5__4)
{
<wasInScoreboard>5__4 = true;
((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.MonitorScoreboard());
}
else if (!<inScoreboard>5__10 & <wasInScoreboard>5__4)
{
<wasInScoreboard>5__4 = false;
<>4__this.ClearPlayerList();
}
if (<shouldBeInLobby>5__11 && !<wasInLobby>5__2)
{
<previousLobbyID>5__1 = <currentLobbyID>5__5;
<>4__this.isInLobby = true;
<wasInLobby>5__2 = true;
<>4__this.ClearPlayerList();
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
}
if (!<shouldBeInLobby>5__11 & <wasInLobby>5__2)
{
<previousLobbyID>5__1 = 0uL;
<>4__this.isInLobby = false;
<wasInLobby>5__2 = false;
<>4__this.ClearPlayerList();
}
else if ((<shouldBeInLobby>5__11 & <wasInLobby>5__2) && <currentLobbyID>5__5 != <previousLobbyID>5__1)
{
<previousLobbyID>5__1 = <currentLobbyID>5__5;
<>4__this.ClearPlayerList();
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
}
break;
}
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 3;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <MonitorPlayers>d__15 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LobbyFriends <>4__this;
private Dictionary<string, string> <previousPlayers>5__1;
private bool <shouldContinue>5__2;
private MainMenuManager <mainMenuManager>5__3;
private Dictionary<string, string> <currentPlayers>5__4;
private Dictionary<string, string>.Enumerator <>s__5;
private KeyValuePair<string, string> <kvp>5__6;
private Dictionary<string, string>.Enumerator <>s__7;
private KeyValuePair<string, string> <kvp>5__8;
private Exception <ex>5__9;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MonitorPlayers>d__15(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<previousPlayers>5__1 = null;
<mainMenuManager>5__3 = null;
<currentPlayers>5__4 = null;
<>s__5 = default(Dictionary<string, string>.Enumerator);
<kvp>5__6 = default(KeyValuePair<string, string>);
<>s__7 = default(Dictionary<string, string>.Enumerator);
<kvp>5__8 = default(KeyValuePair<string, string>);
<ex>5__9 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
//IL_03c0: Expected O, but got Unknown
//IL_0394: Unknown result type (might be due to invalid IL or missing references)
//IL_039e: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<previousPlayers>5__1 = new Dictionary<string, string>();
break;
case 1:
<>1__state = -1;
break;
case 2:
<>1__state = -1;
break;
}
if (<>4__this.isInLobby && !<>4__this.gameStarted)
{
<shouldContinue>5__2 = false;
try
{
<>4__this.CheckForGameStart();
if (<>4__this.gameStarted)
{
<shouldContinue>5__2 = true;
}
else
{
<mainMenuManager>5__3 = Object.FindFirstObjectByType<MainMenuManager>();
if ((Object)(object)<mainMenuManager>5__3 != (Object)null && <mainMenuManager>5__3.GameHasStarted)
{
<shouldContinue>5__2 = true;
}
else
{
<currentPlayers>5__4 = <>4__this.GetConnectedPlayers();
<>s__5 = <currentPlayers>5__4.GetEnumerator();
try
{
while (<>s__5.MoveNext())
{
<kvp>5__6 = <>s__5.Current;
if (!<previousPlayers>5__1.ContainsKey(<kvp>5__6.Key))
{
<>4__this.playerRetryCount[<kvp>5__6.Key] = 0;
}
if (!<>4__this.clickablePlayerButtons.ContainsKey(<kvp>5__6.Key))
{
if (<>4__this.MakePlayerNameClickable(<kvp>5__6.Key, <kvp>5__6.Value))
{
<>4__this.playerRetryCount.Remove(<kvp>5__6.Key);
}
else if (<>4__this.playerRetryCount.ContainsKey(<kvp>5__6.Key))
{
<>4__this.playerRetryCount[<kvp>5__6.Key]++;
if (<>4__this.playerRetryCount[<kvp>5__6.Key] >= 5)
{
ModLogger.LogWarning((object)$"Failed to make {<kvp>5__6.Key} clickable after {5} attempts");
<>4__this.playerRetryCount.Remove(<kvp>5__6.Key);
}
}
}
<kvp>5__6 = default(KeyValuePair<string, string>);
}
}
finally
{
((IDisposable)<>s__5).Dispose();
}
<>s__5 = default(Dictionary<string, string>.Enumerator);
<>s__7 = <previousPlayers>5__1.GetEnumerator();
try
{
while (<>s__7.MoveNext())
{
<kvp>5__8 = <>s__7.Current;
if (!<currentPlayers>5__4.ContainsKey(<kvp>5__8.Key))
{
<>4__this.RemovePlayerClickable(<kvp>5__8.Key);
}
<kvp>5__8 = default(KeyValuePair<string, string>);
}
}
finally
{
((IDisposable)<>s__7).Dispose();
}
<>s__7 = default(Dictionary<string, string>.Enumerator);
<previousPlayers>5__1 = new Dictionary<string, string>(<currentPlayers>5__4);
<currentPlayers>5__4 = null;
}
<mainMenuManager>5__3 = null;
}
}
catch (Exception ex)
{
<ex>5__9 = ex;
ModLogger.LogError((object)("Error monitoring players: " + <ex>5__9.Message));
}
if (<shouldContinue>5__2)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
}
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <MonitorScoreboard>d__22 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LobbyFriends <>4__this;
private Dictionary<string, string> <previousPlayers>5__1;
private int <scoreboardRetryCount>5__2;
private bool <shouldContinue>5__3;
private bool <shouldBreak>5__4;
private Dictionary<string, string> <currentPlayers>5__5;
private bool <scoreboardPopulated>5__6;
private Canvas <scoreboardCanvas>5__7;
private Transform <scoreboard>5__8;
private int <i>5__9;
private Transform <playerSlot>5__10;
private Transform <textComponent>5__11;
private Text <text>5__12;
private Dictionary<string, string>.Enumerator <>s__13;
private KeyValuePair<string, string> <kvp>5__14;
private Dictionary<string, string>.Enumerator <>s__15;
private KeyValuePair<string, string> <kvp>5__16;
private Exception <ex>5__17;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MonitorScoreboard>d__22(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<previousPlayers>5__1 = null;
<currentPlayers>5__5 = null;
<scoreboardCanvas>5__7 = null;
<scoreboard>5__8 = null;
<playerSlot>5__10 = null;
<textComponent>5__11 = null;
<text>5__12 = null;
<>s__13 = default(Dictionary<string, string>.Enumerator);
<kvp>5__14 = default(KeyValuePair<string, string>);
<>s__15 = default(Dictionary<string, string>.Enumerator);
<kvp>5__16 = default(KeyValuePair<string, string>);
<ex>5__17 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0543: Unknown result type (might be due to invalid IL or missing references)
//IL_054d: Expected O, but got Unknown
//IL_0521: Unknown result type (might be due to invalid IL or missing references)
//IL_052b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<previousPlayers>5__1 = new Dictionary<string, string>();
<scoreboardRetryCount>5__2 = 0;
break;
case 1:
<>1__state = -1;
break;
case 2:
<>1__state = -1;
break;
}
if (<>4__this.CheckForScoreboard())
{
<shouldContinue>5__3 = false;
<shouldBreak>5__4 = false;
try
{
<currentPlayers>5__5 = <>4__this.GetConnectedPlayers();
<scoreboardPopulated>5__6 = false;
<scoreboardCanvas>5__7 = FindCanvasByNameInScene("Canvas", "GameScene");
if ((Object)(object)<scoreboardCanvas>5__7 != (Object)null)
{
<scoreboard>5__8 = ((Component)<scoreboardCanvas>5__7).transform.Find("SCoreboard");
if ((Object)(object)<scoreboard>5__8 != (Object)null)
{
<i>5__9 = 1;
while (<i>5__9 <= 8)
{
<playerSlot>5__10 = <scoreboard>5__8.Find($"Player{<i>5__9}");
if ((Object)(object)<playerSlot>5__10 != (Object)null)
{
<textComponent>5__11 = <playerSlot>5__10.Find($"Text (Legacy) {<i>5__9}");
if ((Object)(object)<textComponent>5__11 != (Object)null)
{
<text>5__12 = ((Component)<textComponent>5__11).GetComponent<Text>();
if ((Object)(object)<text>5__12 != (Object)null && !string.IsNullOrEmpty(<text>5__12.text))
{
<scoreboardPopulated>5__6 = true;
break;
}
<text>5__12 = null;
}
<textComponent>5__11 = null;
}
<playerSlot>5__10 = null;
<i>5__9++;
}
}
<scoreboard>5__8 = null;
}
if (!<scoreboardPopulated>5__6)
{
<scoreboardRetryCount>5__2++;
if (<scoreboardRetryCount>5__2 >= 30)
{
ModLogger.LogWarning((object)"Scoreboard not populated after maximum retries - stopping scoreboard monitoring");
<shouldBreak>5__4 = true;
}
else
{
<shouldContinue>5__3 = true;
}
}
else
{
<scoreboardRetryCount>5__2 = 0;
<>s__13 = <currentPlayers>5__5.GetEnumerator();
try
{
while (<>s__13.MoveNext())
{
<kvp>5__14 = <>s__13.Current;
if (!<previousPlayers>5__1.ContainsKey(<kvp>5__14.Key))
{
<>4__this.playerRetryCount[<kvp>5__14.Key] = 0;
}
if (!<>4__this.clickablePlayerButtons.ContainsKey(<kvp>5__14.Key))
{
if (<>4__this.MakeScoreboardPlayerNameClickable(<kvp>5__14.Key, <kvp>5__14.Value))
{
<>4__this.playerRetryCount.Remove(<kvp>5__14.Key);
}
else if (<>4__this.playerRetryCount.ContainsKey(<kvp>5__14.Key))
{
<>4__this.playerRetryCount[<kvp>5__14.Key]++;
if (<>4__this.playerRetryCount[<kvp>5__14.Key] >= 5)
{
ModLogger.LogWarning((object)$"Failed to make scoreboard {<kvp>5__14.Key} clickable after {5} attempts");
<>4__this.playerRetryCount.Remove(<kvp>5__14.Key);
}
}
}
<kvp>5__14 = default(KeyValuePair<string, string>);
}
}
finally
{
((IDisposable)<>s__13).Dispose();
}
<>s__13 = default(Dictionary<string, string>.Enumerator);
<>s__15 = <previousPlayers>5__1.GetEnumerator();
try
{
while (<>s__15.MoveNext())
{
<kvp>5__16 = <>s__15.Current;
if (!<currentPlayers>5__5.ContainsKey(<kvp>5__16.Key))
{
<>4__this.RemovePlayerClickable(<kvp>5__16.Key);
}
<kvp>5__16 = default(KeyValuePair<string, string>);
}
}
finally
{
((IDisposable)<>s__15).Dispose();
}
<>s__15 = default(Dictionary<string, string>.Enumerator);
<previousPlayers>5__1 = new Dictionary<string, string>(<currentPlayers>5__5);
}
<currentPlayers>5__5 = null;
<scoreboardCanvas>5__7 = null;
}
catch (Exception ex)
{
<ex>5__17 = ex;
ModLogger.LogError((object)("Error monitoring scoreboard: " + <ex>5__17.Message));
}
if (!<shouldBreak>5__4)
{
if (<shouldContinue>5__3)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
}
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
}
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public static string modsync = "client";
private static ManualLogSource ModLogger;
private Harmony harmony;
private static LobbyFriends instance;
private Dictionary<string, Button> clickablePlayerButtons = new Dictionary<string, Button>();
private Dictionary<string, string> playerNameToSteamID = new Dictionary<string, string>();
private Dictionary<string, string> connectedPlayers = new Dictionary<string, string>();
private bool isInLobby = false;
private bool gameStarted = false;
private const float UI_UPDATE_INTERVAL = 1f;
private Dictionary<string, int> playerRetryCount = new Dictionary<string, int>();
private const int MAX_RETRY_ATTEMPTS = 5;
private void Awake()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
ModLogger = Logger.CreateLogSource("LobbyFriends");
harmony = new Harmony("com.magearena.lobbyfriends");
instance = this;
((MonoBehaviour)this).StartCoroutine(MonitorLobbyState());
}
private bool MakePlayerNameClickable(string playerName, string steamID)
{
//IL_039e: Unknown result type (might be due to invalid IL or missing references)
//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
//IL_046d: Unknown result type (might be due to invalid IL or missing references)
//IL_0477: Expected O, but got Unknown
//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
//IL_03d1: Expected O, but got Unknown
//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
//IL_0407: Unknown result type (might be due to invalid IL or missing references)
//IL_040e: Expected O, but got Unknown
//IL_0411: 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_024b: Expected O, but got Unknown
//IL_027a: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
//IL_02de: Unknown result type (might be due to invalid IL or missing references)
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
//IL_030f: Unknown result type (might be due to invalid IL or missing references)
try
{
Canvas val = FindCanvasByNameInScene("Canvas (1)", "GameScene");
if ((Object)(object)val == (Object)null)
{
ModLogger.LogWarning((object)"Could not find Canvas (1) in GameScene");
return false;
}
if ((Object)(object)val == (Object)null)
{
ModLogger.LogWarning((object)"Could not find Canvas (1)");
return false;
}
Transform val2 = ((Component)val).transform.Find("Lobby");
if ((Object)(object)val2 == (Object)null)
{
ModLogger.LogWarning((object)"Could not find Lobby container");
return false;
}
Transform val3 = val2.Find("JoinedPlayers");
if ((Object)(object)val3 == (Object)null)
{
ModLogger.LogWarning((object)"Could not find JoinedPlayers container");
return false;
}
for (int i = 0; i < 8; i++)
{
Transform child = val3.GetChild(i);
if ((Object)(object)child == (Object)null)
{
continue;
}
Text[] componentsInChildren = ((Component)child).GetComponentsInChildren<Text>();
bool flag = false;
Text[] array = componentsInChildren;
foreach (Text val4 in array)
{
if (val4.text == playerName)
{
flag = true;
break;
}
}
if (!flag)
{
continue;
}
Text nameText = null;
Text[] array2 = componentsInChildren;
foreach (Text val5 in array2)
{
if (val5.text == playerName)
{
nameText = val5;
break;
}
}
if ((Object)(object)nameText == (Object)null)
{
ModLogger.LogWarning((object)("Could not find nameText component for " + playerName));
return false;
}
GameObject val6 = null;
Button val7 = null;
for (int l = 0; l < child.childCount; l++)
{
Transform child2 = child.GetChild(l);
if (((Object)child2).name == "ClickableOverlay_" + playerName)
{
val6 = ((Component)child2).gameObject;
val7 = val6.GetComponent<Button>();
break;
}
}
if ((Object)(object)val6 == (Object)null)
{
val6 = new GameObject("ClickableOverlay_" + playerName);
val6.transform.SetParent(child, false);
Image val8 = val6.AddComponent<Image>();
((Graphic)val8).color = new Color(0f, 0f, 0f, 0f);
RectTransform component = val6.GetComponent<RectTransform>();
RectTransform component2 = ((Component)nameText).GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
{
try
{
component.anchorMin = component2.anchorMin;
component.anchorMax = component2.anchorMax;
component.anchoredPosition = component2.anchoredPosition;
component.sizeDelta = new Vector2(component2.sizeDelta.x * 0.8f, component2.sizeDelta.y * 0.8f);
}
catch (Exception ex)
{
ModLogger.LogWarning((object)("Error positioning overlay for " + playerName + ": " + ex.Message));
}
}
else
{
ModLogger.LogWarning((object)("Could not get RectTransform components for " + playerName));
}
val7 = val6.AddComponent<Button>();
if ((Object)(object)nameText != (Object)null)
{
Color originalTextColor = ((Graphic)nameText).color;
EventTrigger val9 = val6.GetComponent<EventTrigger>();
if ((Object)(object)val9 == (Object)null)
{
val9 = val6.AddComponent<EventTrigger>();
}
Entry val10 = new Entry();
val10.eventID = (EventTriggerType)0;
((UnityEvent<BaseEventData>)(object)val10.callback).AddListener((UnityAction<BaseEventData>)delegate
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)nameText != (Object)null)
{
((Graphic)nameText).color = new Color(0.917f, 0.7086f, 0.673f, 0.7843f);
}
});
val9.triggers.Add(val10);
Entry val11 = new Entry();
val11.eventID = (EventTriggerType)1;
((UnityEvent<BaseEventData>)(object)val11.callback).AddListener((UnityAction<BaseEventData>)delegate
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)nameText != (Object)null)
{
((Graphic)nameText).color = originalTextColor;
}
});
val9.triggers.Add(val11);
}
}
string capturedSteamID = steamID;
string capturedPlayerName = playerName;
((UnityEventBase)val7.onClick).RemoveAllListeners();
((UnityEvent)val7.onClick).AddListener((UnityAction)delegate
{
OnAddFriendClicked(capturedSteamID, capturedPlayerName);
});
clickablePlayerButtons[playerName] = val7;
playerNameToSteamID[playerName] = steamID;
return true;
}
ModLogger.LogWarning((object)("Could not find UI element for player: " + playerName));
return false;
}
catch (Exception ex2)
{
ModLogger.LogError((object)("Error making player name clickable: " + ex2.Message));
ModLogger.LogError((object)("Stack trace: " + ex2.StackTrace));
return false;
}
}
[IteratorStateMachine(typeof(<MonitorLobbyState>d__14))]
private IEnumerator MonitorLobbyState()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <MonitorLobbyState>d__14(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<MonitorPlayers>d__15))]
private IEnumerator MonitorPlayers()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <MonitorPlayers>d__15(0)
{
<>4__this = this
};
}
private Dictionary<string, string> GetConnectedPlayers()
{
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
Dictionary<string, string> dictionary = new Dictionary<string, string>();
try
{
MainMenuManager val = Object.FindFirstObjectByType<MainMenuManager>();
if ((Object)(object)val != (Object)null && (Object)(object)val.kickplayershold != (Object)null)
{
foreach (KeyValuePair<string, string> item in val.kickplayershold.nametosteamid)
{
dictionary[item.Key] = item.Value;
}
}
if (BootstrapManager.CurrentLobbyID != 0)
{
CSteamID val2 = default(CSteamID);
((CSteamID)(ref val2))..ctor(BootstrapManager.CurrentLobbyID);
int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(val2);
for (int i = 0; i < numLobbyMembers; i++)
{
CSteamID lobbyMemberByIndex = SteamMatchmaking.GetLobbyMemberByIndex(val2, i);
string friendPersonaName = SteamFriends.GetFriendPersonaName(lobbyMemberByIndex);
string value = ((object)(CSteamID)(ref lobbyMemberByIndex)).ToString();
if (!string.IsNullOrEmpty(friendPersonaName) && friendPersonaName != "Unknown")
{
dictionary[friendPersonaName] = value;
}
}
}
}
catch (Exception ex)
{
ModLogger.LogError((object)("Error getting connected players: " + ex.Message));
}
return dictionary;
}
private void RemovePlayerClickable(string playerName)
{
try
{
if (clickablePlayerButtons.ContainsKey(playerName))
{
Button val = clickablePlayerButtons[playerName];
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
clickablePlayerButtons.Remove(playerName);
playerNameToSteamID.Remove(playerName);
}
}
catch (Exception ex)
{
ModLogger.LogError((object)("Error removing player clickable: " + ex.Message));
}
}
private void OnAddFriendClicked(string steamID, string playerName)
{
try
{
string text = "https://steamcommunity.com/profiles/" + steamID + "/";
SteamFriends.ActivateGameOverlayToWebPage(text, (EActivateGameOverlayToWebPageMode)0);
ShowTemporaryMessage("Opening " + playerName + "'s Steam profile...");
}
catch (Exception ex)
{
ModLogger.LogError((object)("Error opening Steam profile: " + ex.Message));
ShowTemporaryMessage("Error opening Steam profile");
}
}
private void ShowTemporaryMessage(string message)
{
try
{
}
catch (Exception ex)
{
ModLogger.LogError((object)("Error showing temporary message: " + ex.Message));
}
}
private void ClearPlayerList()
{
try
{
foreach (KeyValuePair<string, Button> clickablePlayerButton in clickablePlayerButtons)
{
if ((Object)(object)clickablePlayerButton.Value != (Object)null)
{
Object.Destroy((Object)(object)clickablePlayerButton.Value);
}
}
clickablePlayerButtons.Clear();
playerNameToSteamID.Clear();
playerRetryCount.Clear();
}
catch (Exception ex)
{
ModLogger.LogError((object)("Error clearing player list: " + ex.Message));
}
}
private bool CheckForScoreboard()
{
try
{
Canvas val = FindCanvasByNameInScene("Canvas", "GameScene");
if ((Object)(object)val != (Object)null)
{
Transform val2 = ((Component)val).transform.Find("SCoreboard");
if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy)
{
return true;
}
}
}
catch (Exception ex)
{
ModLogger.LogWarning((object)("Error checking for scoreboard: " + ex.Message));
}
return false;
}
[IteratorStateMachine(typeof(<MonitorScoreboard>d__22))]
private IEnumerator MonitorScoreboard()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <MonitorScoreboard>d__22(0)
{
<>4__this = this
};
}
private bool MakeScoreboardPlayerNameClickable(string playerName, string steamID)
{
//IL_038f: Unknown result type (might be due to invalid IL or missing references)
//IL_0394: Unknown result type (might be due to invalid IL or missing references)
//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
//IL_03c2: Expected O, but got Unknown
//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
//IL_03ff: Expected O, but got Unknown
//IL_0402: Unknown result type (might be due to invalid IL or missing references)
//IL_0432: Unknown result type (might be due to invalid IL or missing references)
//IL_0437: Unknown result type (might be due to invalid IL or missing references)
//IL_043b: Unknown result type (might be due to invalid IL or missing references)
//IL_045c: Unknown result type (might be due to invalid IL or missing references)
//IL_047d: Unknown result type (might be due to invalid IL or missing references)
//IL_048a: Unknown result type (might be due to invalid IL or missing references)
//IL_04de: Unknown result type (might be due to invalid IL or missing references)
//IL_04e8: Expected O, but got Unknown
//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
//IL_04f0: Expected O, but got Unknown
//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Expected O, but got Unknown
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
//IL_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_028f: Unknown result type (might be due to invalid IL or missing references)
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
//IL_031e: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Unknown result type (might be due to invalid IL or missing references)
//IL_0333: Unknown result type (might be due to invalid IL or missing references)
//IL_033a: Unknown result type (might be due to invalid IL or missing references)
try
{
Canvas val = FindCanvasByNameInScene("Canvas", "GameScene");
if ((Object)(object)val == (Object)null)
{
ModLogger.LogWarning((object)"Could not find scoreboard Canvas in GameScene");
return false;
}
Transform val2 = ((Component)val).transform.Find("SCoreboard");
if ((Object)(object)val2 == (Object)null)
{
ModLogger.LogWarning((object)"Could not find SCoreboard container");
return false;
}
for (int i = 1; i <= 8; i++)
{
Transform val3 = val2.Find($"Player{i}");
if ((Object)(object)val3 == (Object)null)
{
continue;
}
Transform val4 = val3.Find($"Text (Legacy) {i}");
if ((Object)(object)val4 == (Object)null)
{
continue;
}
Text text = ((Component)val4).GetComponent<Text>();
if ((Object)(object)text == (Object)null || !(text.text == playerName))
{
continue;
}
GameObject val5 = null;
Button val6 = null;
for (int j = 0; j < val3.childCount; j++)
{
Transform child = val3.GetChild(j);
if (((Object)child).name == "Button_" + playerName)
{
val5 = ((Component)child).gameObject;
val6 = val5.GetComponent<Button>();
break;
}
}
if ((Object)(object)val5 == (Object)null)
{
val5 = new GameObject("Button_" + playerName);
val5.transform.SetParent(val2, false);
val6 = val5.AddComponent<Button>();
Image val7 = val5.AddComponent<Image>();
((Graphic)val7).color = new Color(0f, 0f, 0f, 0f);
RectTransform component = val5.GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null)
{
component.anchorMin = new Vector2(0f, 0f);
component.anchorMax = new Vector2(0f, 0f);
component.anchoredPosition = new Vector2(400.48f, 0f);
component.sizeDelta = new Vector2(200f, 50f);
((Transform)component).localScale = new Vector3(0.5f, 0.5f, 0.5f);
}
}
RectTransform component2 = val5.GetComponent<RectTransform>();
RectTransform component3 = ((Component)text).GetComponent<RectTransform>();
if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null)
{
try
{
Vector3 position = ((Component)text).transform.position;
val5.transform.position = new Vector3(400.48f, position.y, position.z);
}
catch (Exception ex)
{
ModLogger.LogWarning((object)("Error re-positioning button for " + playerName + ": " + ex.Message));
}
}
Color originalTextColor = ((Graphic)text).color;
EventTrigger val8 = val5.GetComponent<EventTrigger>();
if ((Object)(object)val8 == (Object)null)
{
val8 = val5.AddComponent<EventTrigger>();
}
Entry val9 = new Entry();
val9.eventID = (EventTriggerType)0;
((UnityEvent<BaseEventData>)(object)val9.callback).AddListener((UnityAction<BaseEventData>)delegate
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)text != (Object)null)
{
((Graphic)text).color = new Color(0.917f, 0.7086f, 0.673f, 0.7843f);
}
});
val8.triggers.Add(val9);
Entry val10 = new Entry();
val10.eventID = (EventTriggerType)1;
((UnityEvent<BaseEventData>)(object)val10.callback).AddListener((UnityAction<BaseEventData>)delegate
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)text != (Object)null)
{
((Graphic)text).color = originalTextColor;
}
});
val8.triggers.Add(val10);
ColorBlock colors = ((Selectable)val6).colors;
((ColorBlock)(ref colors)).normalColor = Color.white;
((ColorBlock)(ref colors)).highlightedColor = new Color(0.917f, 0.7086f, 0.673f, 1f);
((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.6f, 0.5f, 1f);
((Selectable)val6).colors = colors;
string capturedSteamID = steamID;
string capturedPlayerName = playerName;
((UnityEventBase)val6.onClick).RemoveAllListeners();
((UnityEvent)val6.onClick).AddListener((UnityAction)delegate
{
OnAddFriendClicked(capturedSteamID, capturedPlayerName);
});
Entry val11 = new Entry();
val11.eventID = (EventTriggerType)4;
((UnityEvent<BaseEventData>)(object)val11.callback).AddListener((UnityAction<BaseEventData>)delegate
{
OnAddFriendClicked(steamID, playerName);
});
val8.triggers.Add(val11);
clickablePlayerButtons[playerName] = val6;
playerNameToSteamID[playerName] = steamID;
return true;
}
ModLogger.LogWarning((object)("Could not find scoreboard UI element for player: " + playerName));
return false;
}
catch (Exception ex2)
{
ModLogger.LogError((object)("Error making scoreboard player name clickable: " + ex2.Message));
ModLogger.LogError((object)("Stack trace: " + ex2.StackTrace));
return false;
}
}
private void CheckForGameStart()
{
try
{
MainMenuManager val = Object.FindFirstObjectByType<MainMenuManager>();
if (!((Object)(object)val != (Object)null))
{
return;
}
if (val.GameHasStarted)
{
if (!gameStarted)
{
gameStarted = true;
ModLogger.LogInfo((object)"Game started - clearing player list");
ClearPlayerList();
}
}
else if (gameStarted)
{
gameStarted = false;
ModLogger.LogInfo((object)"Returned to lobby");
}
}
catch (Exception ex)
{
ModLogger.LogWarning((object)("Error checking for game start: " + ex.Message));
}
}
private void OnDestroy()
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
}
public static T FindInScene<T>(string sceneName) where T : Component
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Scene sceneByName = SceneManager.GetSceneByName(sceneName);
if (!((Scene)(ref sceneByName)).IsValid() || !((Scene)(ref sceneByName)).isLoaded)
{
return default(T);
}
GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
foreach (GameObject val in rootGameObjects)
{
T componentInChildren = val.GetComponentInChildren<T>(true);
if (Object.op_Implicit((Object)(object)componentInChildren))
{
return componentInChildren;
}
}
return default(T);
}
public static Canvas FindCanvasByNameInScene(string canvasName, string sceneName)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Scene sceneByName = SceneManager.GetSceneByName(sceneName);
if (!((Scene)(ref sceneByName)).IsValid() || !((Scene)(ref sceneByName)).isLoaded)
{
return null;
}
GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
foreach (GameObject val in rootGameObjects)
{
Canvas[] componentsInChildren = val.GetComponentsInChildren<Canvas>(true);
Canvas[] array = componentsInChildren;
foreach (Canvas val2 in array)
{
if (((Object)val2).name == canvasName)
{
return val2;
}
}
}
return null;
}
public static bool IsInLobby()
{
return instance?.isInLobby ?? false;
}
public static int GetPlayerCount()
{
return instance?.clickablePlayerButtons.Count ?? 0;
}
public static void ForceRefreshPlayers()
{
if (!((Object)(object)instance != (Object)null))
{
return;
}
instance.ClearPlayerList();
Dictionary<string, string> dictionary = instance.GetConnectedPlayers();
foreach (KeyValuePair<string, string> item in dictionary)
{
instance.MakePlayerNameClickable(item.Key, item.Value);
}
}
}