Decompiled source of PlayersTab v1.0.0

BepInEx/plugins/AntsLab.PlayersTab/PlayersTab.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("PlayersTab")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PlayersTab")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9d2255b4-a2c4-470c-9536-98e86eb6a7ae")]
[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 AntsLab.PlayersTab;

[BepInPlugin("antslab.playerstab", "AntsLab PlayersTab", "1.0.0")]
public class PlayersTabPlugin : BaseUnityPlugin
{
	private struct PlayerEntry
	{
		public string Name;

		public int Team;

		public GameObject GO;
	}

	public const string PluginGuid = "antslab.playerstab";

	public const string PluginName = "AntsLab PlayersTab";

	public const string PluginVersion = "1.0.0";

	internal static PlayersTabPlugin Instance;

	private Harmony _harmony;

	internal static ConfigEntry<KeyCode> KeyBind;

	private ConfigEntry<float> _anchorXPct;

	private ConfigEntry<float> _anchorYPct;

	private ConfigEntry<float> _panelWidth;

	private ConfigEntry<int> _fontSize;

	private ConfigEntry<float> _rowHeight;

	private ConfigEntry<float> _refreshSec;

	private ConfigEntry<bool> _useMenuFont;

	private ConfigEntry<bool> _showNamelessPlayers;

	private readonly List<PlayerEntry> _players = new List<PlayerEntry>();

	private float _nextRefresh;

	private GUIStyle _rowStyle;

	private GUIStyle _hdrStyle;

	private Font _menuFont;

	private void Awake()
	{
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		Instance = this;
		KeyBind = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("UI", "KeyBind", (KeyCode)9, "Default Bind to hold and show the players (I recommend to set to the same bind you use to open the map).");
		_anchorXPct = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "AnchorXPct", 0.255f, "X % of screen (0..1).");
		_anchorYPct = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "AnchorYPct", 0.27f, "Y % of screen (0..1) (0=top;1=bottom).");
		_panelWidth = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "PanelWidth", 360f, "Panel Width (is invisible) (in px).");
		_fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "FontSize", 26, "Text size (px).");
		_rowHeight = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "RowHeight", 35f, "Height of each line (px).");
		_refreshSec = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "RefreshSeconds", 2f, "List update interval in seconds (s).");
		_useMenuFont = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "UseMenuFont", true, "If true attempts to use the same font as the one on game's Menu.");
		_showNamelessPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowNamelessPlayers", true, "If true players that fail to render the name will show as \"nameless\" meaning will show players as nameless during lobby. Otherwise, it will not even render the tab on lobby");
		_harmony = new Harmony("antslab.playerstab");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"AntsLab PlayersTab 1.0.0 loaded.");
	}

	private void OnDestroy()
	{
		try
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch
		{
		}
		Instance = null;
	}

	private void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKey(KeyBind.Value) && Time.unscaledTime >= _nextRefresh)
		{
			_nextRefresh = Time.unscaledTime + Mathf.Max(0.1f, _refreshSec.Value);
			RefreshPlayers();
		}
	}

	private void OnGUI()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0318: Unknown result type (might be due to invalid IL or missing references)
		//IL_0336: Unknown result type (might be due to invalid IL or missing references)
		//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		if (!Input.GetKey(KeyBind.Value))
		{
			return;
		}
		BuildStylesIfNeeded();
		List<PlayerEntry> list = (from p in _players
			where p.Team == 0
			orderby p.Name
			select p).ToList();
		List<PlayerEntry> list2 = (from p in _players
			where p.Team == 2
			orderby p.Name
			select p).ToList();
		List<PlayerEntry> list3 = (from p in _players
			where p.Team != 0 && p.Team != 2
			orderby p.Name
			select p).ToList();
		int num = ((list.Count > 0) ? 1 : 0) + ((list2.Count > 0) ? 1 : 0) + ((list3.Count > 0) ? 1 : 0);
		int num2 = list.Count + list2.Count + list3.Count;
		float num3 = Mathf.Clamp(_panelWidth.Value, 200f, 800f);
		float num4 = Mathf.Clamp(_rowHeight.Value, 16f, 48f);
		float num5 = num4 + 2f;
		float num6 = (float)num * num5 + (float)num2 * num4 + 10f;
		float num7 = Mathf.Round(Mathf.Clamp01(_anchorXPct.Value) * (float)Screen.width);
		float num8 = Mathf.Round(Mathf.Clamp01(_anchorYPct.Value) * (float)Screen.height);
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(num7, num8, num3, num6);
		Color color = GUI.color;
		GUI.color = new Color(0f, 0f, 0f, 0f);
		GUI.Box(val, GUIContent.none);
		GUI.color = color;
		float num9 = ((Rect)(ref val)).y + 5f;
		float num10 = ((Rect)(ref val)).x + 10f;
		float num11 = ((Rect)(ref val)).width - 20f;
		if (list.Count > 0)
		{
			DrawHeader(new Rect(num10, num9, num11, num5), "Sorcerers", new Color(0.3f, 0.6f, 1f, 1f));
			num9 += num5;
			for (int i = 0; i < list.Count; i++)
			{
				DrawRow(new Rect(num10, num9, num11, num4), list[i].Name);
				num9 += num4;
			}
		}
		if (list2.Count > 0)
		{
			DrawHeader(new Rect(num10, num9, num11, num5), "Warlocks", new Color(0.7f, 0.5f, 1f, 1f));
			num9 += num5;
			for (int j = 0; j < list2.Count; j++)
			{
				DrawRow(new Rect(num10, num9, num11, num4), list2[j].Name);
				num9 += num4;
			}
		}
		if (list3.Count > 0)
		{
			DrawHeader(new Rect(num10, num9, num11, num5), "Others", new Color(0.8f, 0.8f, 0.8f, 1f));
			num9 += num5;
			for (int k = 0; k < list3.Count; k++)
			{
				DrawRow(new Rect(num10, num9, num11, num4), list3[k].Name);
				num9 += num4;
			}
		}
	}

	private void DrawHeader(Rect rectHeader, string text, Color color)
	{
		//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_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		Color color2 = GUI.color;
		GUI.color = color;
		GUI.Label(rectHeader, text, _hdrStyle);
		GUI.color = color2;
	}

	private void DrawRow(Rect rectRow, string name)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		GUI.Label(rectRow, name, _rowStyle);
	}

	private void BuildStylesIfNeeded()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		if (_rowStyle != null && _hdrStyle != null)
		{
			return;
		}
		_rowStyle = new GUIStyle(GUI.skin.label);
		_rowStyle.alignment = (TextAnchor)3;
		_rowStyle.fontSize = Mathf.Max(12, _fontSize.Value);
		_rowStyle.wordWrap = false;
		_hdrStyle = new GUIStyle(GUI.skin.label);
		_hdrStyle.alignment = (TextAnchor)3;
		_hdrStyle.fontStyle = (FontStyle)1;
		_hdrStyle.fontSize = Mathf.Max(12, _fontSize.Value + 2);
		_hdrStyle.wordWrap = false;
		if (_useMenuFont.Value)
		{
			Font val = TryGetMenuFontFromTMP();
			if ((Object)(object)val != (Object)null)
			{
				_rowStyle.font = val;
				_hdrStyle.font = val;
			}
		}
	}

	private static Font TryGetMenuFontFromTMP()
	{
		try
		{
			ScriptableObject[] array = Resources.FindObjectsOfTypeAll<ScriptableObject>();
			foreach (ScriptableObject val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				if (type.FullName == "TMPro.TMP_FontAsset" && ((Object)val).name.IndexOf("KELMSCOT", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					PropertyInfo property = type.GetProperty("sourceFontFile", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					Font val2 = (Font)((property != null) ? /*isinst with value type is only supported in some contexts*/: null);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private void RefreshPlayers()
	{
		_players.Clear();
		int num = 1;
		Component[] array = FindAllComponentsSafe();
		foreach (Component val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Type type = ((object)val).GetType();
			if (type == null || type.Name != "PlayerMovement")
			{
				continue;
			}
			GameObject gameObject = val.gameObject;
			if (!((Object)(object)gameObject == (Object)null) && gameObject.activeInHierarchy)
			{
				int intField = GetIntField(val, "playerTeam", -1);
				string text = GetStringField(val, "playername", null);
				if (string.IsNullOrEmpty(text) && _showNamelessPlayers.Value)
				{
					text = "nameless " + num;
					num++;
				}
				if (!string.IsNullOrEmpty(text) || _showNamelessPlayers.Value)
				{
					_players.Add(new PlayerEntry
					{
						GO = gameObject,
						Team = intField,
						Name = text
					});
				}
			}
		}
	}

	private static Component[] FindAllComponentsSafe()
	{
		try
		{
			MethodInfo method = typeof(Object).GetMethod("FindObjectsByType", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
			{
				typeof(Type),
				typeof(FindObjectsSortMode)
			}, null);
			if (method != null && method.Invoke(null, new object[2]
			{
				typeof(Component),
				(object)(FindObjectsSortMode)0
			}) is Array array)
			{
				Component[] array2 = (Component[])(object)new Component[array.Length];
				Array.Copy(array, array2, array.Length);
				return array2;
			}
		}
		catch
		{
		}
		return (Component[])(object)new Component[0];
	}

	private static int GetIntField(Component c, string field, int def)
	{
		try
		{
			FieldInfo field2 = ((object)c).GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 == null)
			{
				return def;
			}
			object value = field2.GetValue(c);
			if (value == null)
			{
				return def;
			}
			if (value.GetType().IsEnum)
			{
				return Convert.ToInt32(value);
			}
			return Convert.ToInt32(value);
		}
		catch
		{
			return def;
		}
	}

	private static string GetStringField(Component c, string field, string def)
	{
		try
		{
			FieldInfo field2 = ((object)c).GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 == null)
			{
				return def;
			}
			object value = field2.GetValue(c);
			return (value != null) ? value.ToString() : def;
		}
		catch
		{
			return def;
		}
	}
}