Decompiled source of MorePlayerList PingAddon v1.2.1

MorePlayerList.PingAddon.dll

Decompiled 11 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
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: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MorePlayerList.PingAddon")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MorePlayerList.PingAddon")]
[assembly: AssemblyTitle("MorePlayerList.PingAddon")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MorePlayerList.PingAddon
{
	[BepInPlugin("MaDeSu.MorePlayerList.PingAddon", "MorePlayerList Ping Addon", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class PingAddonPlugin : BaseUnityPlugin
	{
		public const string GUID = "MaDeSu.MorePlayerList.PingAddon";

		public const string Version = "1.1.0";

		internal static ManualLogSource Log;

		private readonly Harmony harmony = new Harmony("MaDeSu.MorePlayerList.PingAddon");

		public static ConfigEntry<bool> ShowPing;

		public static ConfigEntry<int> FontSize;

		public static ConfigEntry<float> XOffset;

		public static ConfigEntry<float> YOffset;

		public static ConfigEntry<int> GreenThreshold;

		public static ConfigEntry<int> YellowThreshold;

		public static ConfigEntry<int> OrangeThreshold;

		private void Awake()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ShowPing = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Show Ping", true, "Show each player's ping next to their entry in the ESC menu list.");
			FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "Font size", 14, new ConfigDescription("Font size of the ping label.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 32), Array.Empty<object>()));
			XOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "X offset", 10f, new ConfigDescription("Gap between the ping label and the left edge of the player's row (negative = further left, this is NOT relative to the row's center).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-400f, 400f), Array.Empty<object>()));
			YOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Y offset", 0f, new ConfigDescription("Vertical offset of the ping label relative to the player's slider.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			GreenThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("Colors", "Green threshold", 50, new ConfigDescription("Ping (ms) below this value is shown in green.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>()));
			YellowThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("Colors", "Yellow threshold", 100, new ConfigDescription("Ping (ms) below this value is shown in yellow.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>()));
			OrangeThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("Colors", "Orange threshold", 200, new ConfigDescription("Ping (ms) below this value is shown in orange, otherwise red.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>()));
			ShowPing.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			FontSize.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			XOffset.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			YOffset.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			GreenThreshold.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			YellowThreshold.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			OrangeThreshold.SettingChanged += delegate
			{
				EscPingPatch.RefreshAll();
			};
			harmony.PatchAll();
			Log.LogInfo((object)"MorePlayerList Ping Addon loaded.");
		}
	}
	[HarmonyPatch(typeof(MenuPageEsc), "Update")]
	public static class EscPingPatch
	{
		private static readonly FieldInfo SlidersField = AccessTools.Field(typeof(MenuPageEsc), "playerMicGainSliders");

		private static readonly FieldInfo PingField = FindPingField();

		private static readonly Dictionary<PlayerAvatar, Text> pingTexts = new Dictionary<PlayerAvatar, Text>();

		private static Font cachedFont;

		private static FieldInfo FindPingField()
		{
			string[] array = new string[3] { "playerPing", "PlayerPing", "ping" };
			string[] array2 = array;
			foreach (string name in array2)
			{
				FieldInfo field = typeof(PlayerAvatar).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field;
				}
			}
			ManualLogSource log = PingAddonPlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)"MorePlayerList.PingAddon: could not find a ping field on PlayerAvatar - ping display disabled.");
			}
			return null;
		}

		private static void Postfix(MenuPageEsc __instance)
		{
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			if (!PingAddonPlugin.ShowPing.Value || PingField == null || SlidersField == null || !(SlidersField.GetValue(__instance) is Dictionary<PlayerAvatar, MenuSliderPlayerMicGain> { Count: not 0 } dictionary))
			{
				return;
			}
			CleanupStaleEntries(dictionary);
			foreach (KeyValuePair<PlayerAvatar, MenuSliderPlayerMicGain> item in dictionary)
			{
				PlayerAvatar key = item.Key;
				MenuSliderPlayerMicGain value = item.Value;
				if (key != null && value != null)
				{
					if (!pingTexts.TryGetValue(key, out var value2) || (Object)(object)value2 == (Object)null)
					{
						value2 = CreatePingText(((Component)value).transform);
						pingTexts[key] = value2;
					}
					int ping = GetPing(key);
					bool flag = !IsLocalPlayer(key) && IsHost(key);
					string arg = (flag ? "[H] " : "");
					value2.text = ((ping >= 0) ? $"{arg}{ping}ms" : (flag ? "[H] --" : "--"));
					((Graphic)value2).color = GetPingColor(ping);
				}
			}
		}

		private static void CleanupStaleEntries(Dictionary<PlayerAvatar, MenuSliderPlayerMicGain> current)
		{
			List<PlayerAvatar> list = null;
			foreach (KeyValuePair<PlayerAvatar, Text> pingText in pingTexts)
			{
				if (pingText.Key == null || !current.ContainsKey(pingText.Key) || (Object)(object)pingText.Value == (Object)null)
				{
					(list ?? (list = new List<PlayerAvatar>())).Add(pingText.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (PlayerAvatar item in list)
			{
				pingTexts.Remove(item);
			}
		}

		public static void RefreshAll()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<PlayerAvatar, Text> pingText in pingTexts)
			{
				Text value = pingText.Value;
				if (!((Object)(object)value == (Object)null))
				{
					RectTransform rectTransform = ((Graphic)value).rectTransform;
					rectTransform.anchoredPosition = new Vector2(PingAddonPlugin.XOffset.Value, PingAddonPlugin.YOffset.Value);
					value.fontSize = PingAddonPlugin.FontSize.Value;
					((Component)value).gameObject.SetActive(PingAddonPlugin.ShowPing.Value);
				}
			}
		}

		private static int GetPing(PlayerAvatar player)
		{
			try
			{
				if (PingField.GetValue(player) is int result)
				{
					return result;
				}
				return -1;
			}
			catch
			{
				return -1;
			}
		}

		private static bool IsLocalPlayer(PlayerAvatar player)
		{
			try
			{
				PhotonView component = ((Component)player).GetComponent<PhotonView>();
				return (Object)(object)component != (Object)null && component.IsMine;
			}
			catch
			{
				return false;
			}
		}

		private static bool IsHost(PlayerAvatar player)
		{
			try
			{
				PhotonView component = ((Component)player).GetComponent<PhotonView>();
				if ((Object)(object)component == (Object)null)
				{
					return false;
				}
				Player owner = component.Owner;
				return owner != null && owner.IsMasterClient;
			}
			catch
			{
				return false;
			}
		}

		private static Color GetPingColor(int ping)
		{
			//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)
			//IL_0045: 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_00b8: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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)
			if (ping < 0)
			{
				return new Color(0.5f, 0.5f, 0.5f);
			}
			if (ping < PingAddonPlugin.GreenThreshold.Value)
			{
				return new Color(0f, 1f, 0.4f);
			}
			if (ping < PingAddonPlugin.YellowThreshold.Value)
			{
				return new Color(1f, 0.9f, 0f);
			}
			if (ping < PingAddonPlugin.OrangeThreshold.Value)
			{
				return new Color(1f, 0.55f, 0f);
			}
			return new Color(1f, 0.2f, 0.2f);
		}

		private static Text CreatePingText(Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PingAddon_PingText");
			val.transform.SetParent(parent, false);
			val.layer = ((Component)parent).gameObject.layer;
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(80f, 20f);
			val2.anchorMin = new Vector2(0f, 0.5f);
			val2.anchorMax = new Vector2(0f, 0.5f);
			val2.pivot = new Vector2(1f, 0.5f);
			val2.anchoredPosition = new Vector2(PingAddonPlugin.XOffset.Value, PingAddonPlugin.YOffset.Value);
			Text val3 = val.AddComponent<Text>();
			val3.font = GetFont();
			val3.fontSize = PingAddonPlugin.FontSize.Value;
			val3.alignment = (TextAnchor)5;
			val3.text = "";
			Outline val4 = val.AddComponent<Outline>();
			((Shadow)val4).effectColor = Color.black;
			((Shadow)val4).effectDistance = new Vector2(1f, -1f);
			return val3;
		}

		private static Font GetFont()
		{
			if ((Object)(object)cachedFont != (Object)null)
			{
				return cachedFont;
			}
			try
			{
				cachedFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			catch
			{
			}
			if ((Object)(object)cachedFont == (Object)null)
			{
				try
				{
					Object builtinResource = Resources.GetBuiltinResource(typeof(Font), "LegacyRuntime.ttf");
					cachedFont = (Font)(object)((builtinResource is Font) ? builtinResource : null);
				}
				catch
				{
				}
			}
			if ((Object)(object)cachedFont == (Object)null)
			{
				cachedFont = Font.CreateDynamicFontFromOSFont("Arial", 14);
			}
			return cachedFont;
		}
	}
}