Decompiled source of MuteAndHostMarker v4.0.0

MuteAndHostMarker.dll

Decompiled 17 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 REPOJP.MuteAndHostMarker
{
	[BepInPlugin("REPOJP.MuteAndHostMarker", "MuteAndHostMarker", "4.0.0")]
	public class MuteAndHostMarkerPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.MuteAndHostMarker";

		public const string PluginName = "MuteAndHostMarker";

		public const string PluginVersion = "4.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ShowSelfMuteMarkerConfig;

		internal static ConfigEntry<string> SelfMuteMarkerTextConfig;

		internal static ConfigEntry<string> SelfMuteMarkerColorConfig;

		internal static ConfigEntry<bool> ShowLocalVolumeMuteStrikethroughConfig;

		internal static ConfigEntry<float> LocalVolumeMuteThresholdConfig;

		internal static ConfigEntry<bool> ShowHostMarkerConfig;

		internal static ConfigEntry<string> HostMarkerTextConfig;

		internal static ConfigEntry<string> HostMarkerColorConfig;

		internal static ConfigEntry<int> HostMarkerSizePercentConfig;

		internal static ConfigEntry<bool> ShowHostMarkerWhenSelfHostConfig;

		internal static ConfigEntry<bool> ShowSelfConfig;

		internal static ConfigEntry<bool> ShowWorldNameConfig;

		internal static ConfigEntry<bool> ShowLobbyListConfig;

		internal static ConfigEntry<bool> ShowEscListConfig;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			try
			{
				Log = ((BaseUnityPlugin)this).Logger;
				((Component)this).transform.parent = null;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				BindConfig();
				harmony = new Harmony("REPOJP.MuteAndHostMarker");
				harmony.PatchAll(typeof(MuteAndHostMarkerPatches));
				Log.LogInfo((object)"MuteAndHostMarker loaded. Version: 4.0.0");
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: MuteAndHostMarker Awake\n" + ex));
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: MuteAndHostMarker OnDestroy\n" + ex));
				}
			}
		}

		private void BindConfig()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			ShowSelfMuteMarkerConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("SelfMuteMarker", "ShowSelfMuteMarker", true, "Show [M] when the target player has muted their own microphone.対象プレイヤー本人が自分のマイクをミュートしている場合に[M]を表示します。");
			SelfMuteMarkerTextConfig = ((BaseUnityPlugin)this).Config.Bind<string>("SelfMuteMarker", "SelfMuteMarkerText", "[M]", "Marker text for self microphone mute.本人マイクミュート表示の文字列です。");
			SelfMuteMarkerColorConfig = ((BaseUnityPlugin)this).Config.Bind<string>("SelfMuteMarker", "SelfMuteMarkerColor", "#FF0000", "Marker color for self microphone mute.本人マイクミュート表示の色です。");
			ShowLocalVolumeMuteStrikethroughConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("LocalVolumeMuteMarker", "ShowLocalVolumeMuteStrikethrough", true, "Apply strikethrough when your local volume for the target player is zero.自分側で対象プレイヤーの音量が0の場合に取り消し線を表示します。");
			LocalVolumeMuteThresholdConfig = ((BaseUnityPlugin)this).Config.Bind<float>("LocalVolumeMuteMarker", "LocalVolumeMuteThreshold", 0.001f, new ConfigDescription("Threshold treated as local volume mute.自分側の音量0扱いにする閾値です。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ShowHostMarkerConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("HostMarker", "ShowHostMarker", true, "Show the host marker from participant view.参加者目線でホストマークを表示します。");
			HostMarkerTextConfig = ((BaseUnityPlugin)this).Config.Bind<string>("HostMarker", "HostMarkerText", "★", "Marker text for host.ホスト表示の文字列です。");
			HostMarkerColorConfig = ((BaseUnityPlugin)this).Config.Bind<string>("HostMarker", "HostMarkerColor", "#FFD700", "Marker color for host.ホスト表示の色です。");
			HostMarkerSizePercentConfig = ((BaseUnityPlugin)this).Config.Bind<int>("HostMarker", "HostMarkerSizePercent", 130, new ConfigDescription("Host marker size percent.ホスト表示のサイズ倍率です。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 300), Array.Empty<object>()));
			ShowHostMarkerWhenSelfHostConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("HostMarker", "ShowHostMarkerWhenSelfHost", false, "Show the host marker even when you are the host.自分がホストの場合もホストマークを表示します。");
			ShowSelfConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowSelf", true, "Apply markers to yourself where UI exists.対象UIが存在する場合に自分自身へも表示します。");
			ShowWorldNameConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowWorldName", true, "Apply markers to world nameplates.頭上ネームプレートへ表示します。");
			ShowLobbyListConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowLobbyList", true, "Apply markers to the lobby player list.ロビーメニュー一覧へ表示します。");
			ShowEscListConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowEscList", true, "Apply markers to the ESC player list.ESCメニュー一覧へ表示します。");
		}
	}
	internal static class MuteAndHostMarkerApplier
	{
		private static readonly Dictionary<int, string> LastAppliedByTextId = new Dictionary<int, string>();

		private static readonly Dictionary<int, string> LastBaseByTextId = new Dictionary<int, string>();

		private static readonly Dictionary<int, PlayerAvatar> LastAvatarByTextId = new Dictionary<int, PlayerAvatar>();

		private static readonly Dictionary<int, TMP_Text> LastTextByTextId = new Dictionary<int, TMP_Text>();

		internal static void ApplyWorldName(PlayerAvatar avatar)
		{
			if (ConfigReady() && MuteAndHostMarkerPlugin.ShowWorldNameConfig.Value)
			{
				WorldSpaceUIPlayerName worldSpaceUIPlayerName = ReflectionCache.GetWorldSpaceUIPlayerName(avatar);
				ApplyWorldNameComponent(worldSpaceUIPlayerName);
			}
		}

		internal static void ApplyWorldNameComponent(WorldSpaceUIPlayerName worldName)
		{
			if (ConfigReady() && MuteAndHostMarkerPlugin.ShowWorldNameConfig.Value && !((Object)(object)worldName == (Object)null) && !((Object)(object)worldName.text == (Object)null))
			{
				PlayerAvatar worldNamePlayerAvatar = ReflectionCache.GetWorldNamePlayerAvatar(worldName);
				if (!((Object)(object)worldNamePlayerAvatar == (Object)null))
				{
					ApplyText(worldNamePlayerAvatar, (TMP_Text)(object)worldName.text);
				}
			}
		}

		internal static void ApplyLobbyListed(MenuPlayerListed listed)
		{
			if (ConfigReady() && MuteAndHostMarkerPlugin.ShowLobbyListConfig.Value && !((Object)(object)listed == (Object)null) && !((Object)(object)listed.playerName == (Object)null))
			{
				PlayerAvatar menuPlayerListedAvatar = ReflectionCache.GetMenuPlayerListedAvatar(listed);
				ApplyText(menuPlayerListedAvatar, (TMP_Text)(object)listed.playerName);
			}
		}

		internal static void ApplyEscSlider(MenuSliderPlayerMicGain slider)
		{
			if (ConfigReady() && MuteAndHostMarkerPlugin.ShowEscListConfig.Value && !((Object)(object)slider == (Object)null))
			{
				PlayerAvatar menuSliderPlayerAvatar = ReflectionCache.GetMenuSliderPlayerAvatar(slider);
				TMP_Text menuSliderNameText = ReflectionCache.GetMenuSliderNameText(slider, menuSliderPlayerAvatar);
				ApplyText(menuSliderPlayerAvatar, menuSliderNameText);
			}
		}

		internal static void ApplyMenuPageEsc(MenuPageEsc page)
		{
			if (!ConfigReady() || !MuteAndHostMarkerPlugin.ShowEscListConfig.Value || (Object)(object)page == (Object)null)
			{
				return;
			}
			Dictionary<PlayerAvatar, MenuSliderPlayerMicGain> escSliders = ReflectionCache.GetEscSliders(page);
			if (escSliders == null)
			{
				return;
			}
			foreach (KeyValuePair<PlayerAvatar, MenuSliderPlayerMicGain> item in escSliders)
			{
				ApplyEscSlider(item.Value);
			}
			CleanupDeadTextTargets();
		}

		internal static void ApplyMenuPageLobby(MenuPageLobby page)
		{
			if (!ConfigReady() || !MuteAndHostMarkerPlugin.ShowLobbyListConfig.Value || (Object)(object)page == (Object)null)
			{
				return;
			}
			List<GameObject> lobbyListObjects = ReflectionCache.GetLobbyListObjects(page);
			if (lobbyListObjects == null)
			{
				return;
			}
			foreach (GameObject item in lobbyListObjects)
			{
				if (!((Object)(object)item == (Object)null))
				{
					MenuPlayerListed component = item.GetComponent<MenuPlayerListed>();
					ApplyLobbyListed(component);
				}
			}
			CleanupDeadTextTargets();
		}

		internal static void ClearCache()
		{
			LastAppliedByTextId.Clear();
			LastBaseByTextId.Clear();
			LastAvatarByTextId.Clear();
			LastTextByTextId.Clear();
		}

		internal static void RefreshKnownTargetsForAvatar(PlayerAvatar avatar)
		{
			if (!ConfigReady() || (Object)(object)avatar == (Object)null)
			{
				return;
			}
			List<TMP_Text> list = new List<TMP_Text>();
			foreach (KeyValuePair<int, PlayerAvatar> item in LastAvatarByTextId)
			{
				if (!((Object)(object)item.Value != (Object)(object)avatar) && LastTextByTextId.TryGetValue(item.Key, out var value) && (Object)(object)value != (Object)null)
				{
					list.Add(value);
				}
			}
			foreach (TMP_Text item2 in list)
			{
				ApplyText(avatar, item2);
			}
		}

		internal static void RefreshKnownTargetsBySteamId(string steamId)
		{
			if (!ConfigReady() || string.IsNullOrEmpty(steamId))
			{
				return;
			}
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			foreach (KeyValuePair<int, PlayerAvatar> item in LastAvatarByTextId)
			{
				PlayerAvatar value = item.Value;
				if (!((Object)(object)value == (Object)null) && ReflectionCache.GetAvatarSteamId(value) == steamId && !list.Contains(value))
				{
					list.Add(value);
				}
			}
			foreach (PlayerAvatar item2 in list)
			{
				RefreshKnownTargetsForAvatar(item2);
			}
		}

		internal static void RefreshAllKnownTargets()
		{
			if (!ConfigReady())
			{
				return;
			}
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			foreach (KeyValuePair<int, PlayerAvatar> item in LastAvatarByTextId)
			{
				PlayerAvatar value = item.Value;
				if ((Object)(object)value != (Object)null && !list.Contains(value))
				{
					list.Add(value);
				}
			}
			foreach (PlayerAvatar item2 in list)
			{
				RefreshKnownTargetsForAvatar(item2);
			}
		}

		private static void ApplyText(PlayerAvatar avatar, TMP_Text text)
		{
			if (!((Object)(object)avatar == (Object)null) && !((Object)(object)text == (Object)null) && (MuteAndHostMarkerPlugin.ShowSelfConfig.Value || !ReflectionCache.GetAvatarIsLocal(avatar)))
			{
				if (!text.richText)
				{
					text.richText = true;
				}
				int instanceID = ((Object)text).GetInstanceID();
				string text2 = text.text ?? string.Empty;
				string baseText = GetBaseText(instanceID, avatar, text2);
				string text3 = BuildDecoratedName(avatar, baseText);
				if (text3 != text2)
				{
					text.text = text3;
				}
				LastAppliedByTextId[instanceID] = text3;
				LastBaseByTextId[instanceID] = baseText;
				LastAvatarByTextId[instanceID] = avatar;
				LastTextByTextId[instanceID] = text;
			}
		}

		private static string GetBaseText(int textId, PlayerAvatar avatar, string currentText)
		{
			if (LastAppliedByTextId.TryGetValue(textId, out var value) && LastBaseByTextId.TryGetValue(textId, out var value2) && LastAvatarByTextId.TryGetValue(textId, out var value3) && (Object)(object)value3 == (Object)(object)avatar && currentText == value)
			{
				return value2;
			}
			string text = MuteAndHostMarkerFormatter.StripOwnDecorations(currentText);
			if (!string.IsNullOrEmpty(text))
			{
				return text;
			}
			string avatarPlayerName = ReflectionCache.GetAvatarPlayerName(avatar);
			if (!string.IsNullOrEmpty(avatarPlayerName))
			{
				return avatarPlayerName;
			}
			return currentText;
		}

		private static string BuildDecoratedName(PlayerAvatar avatar, string baseText)
		{
			string text = baseText ?? string.Empty;
			if (MuteAndHostMarkerPlugin.ShowLocalVolumeMuteStrikethroughConfig.Value && IsLocalVolumeMuted(avatar))
			{
				text = "<s>" + text + "</s>";
			}
			if (MuteAndHostMarkerPlugin.ShowSelfMuteMarkerConfig.Value && IsSelfMicrophoneMuted(avatar))
			{
				text = MuteAndHostMarkerFormatter.GetSelfMutePrefix() + " " + text;
			}
			if (MuteAndHostMarkerPlugin.ShowHostMarkerConfig.Value && IsHostAvatar(avatar))
			{
				text = MuteAndHostMarkerFormatter.GetHostPrefix() + " " + text;
			}
			return text;
		}

		private static bool IsSelfMicrophoneMuted(PlayerAvatar avatar)
		{
			PlayerVoiceChat avatarVoiceChat = ReflectionCache.GetAvatarVoiceChat(avatar);
			if ((Object)(object)avatarVoiceChat == (Object)null)
			{
				return false;
			}
			return ReflectionCache.GetVoiceChatToggleMute(avatarVoiceChat);
		}

		private static bool IsLocalVolumeMuted(PlayerAvatar avatar)
		{
			if ((Object)(object)GameManager.instance == (Object)null)
			{
				return false;
			}
			string avatarSteamId = ReflectionCache.GetAvatarSteamId(avatar);
			if (string.IsNullOrEmpty(avatarSteamId))
			{
				return false;
			}
			float num = GameManager.instance.PlayerMicrophoneSettingGet(avatarSteamId);
			return num <= Mathf.Max(0f, MuteAndHostMarkerPlugin.LocalVolumeMuteThresholdConfig.Value);
		}

		private static bool IsHostAvatar(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null || (Object)(object)avatar.photonView == (Object)null)
			{
				return false;
			}
			if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom || PhotonNetwork.MasterClient == null)
			{
				return false;
			}
			if (PhotonNetwork.IsMasterClient && !MuteAndHostMarkerPlugin.ShowHostMarkerWhenSelfHostConfig.Value)
			{
				return false;
			}
			return avatar.photonView.OwnerActorNr == PhotonNetwork.MasterClient.ActorNumber;
		}

		private static bool ConfigReady()
		{
			return MuteAndHostMarkerPlugin.ShowSelfConfig != null;
		}

		private static void CleanupDeadTextTargets()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, PlayerAvatar> item in LastAvatarByTextId)
			{
				if ((Object)(object)item.Value == (Object)null)
				{
					list.Add(item.Key);
				}
			}
			foreach (int item2 in list)
			{
				LastAppliedByTextId.Remove(item2);
				LastBaseByTextId.Remove(item2);
				LastAvatarByTextId.Remove(item2);
				LastTextByTextId.Remove(item2);
			}
		}
	}
	internal static class MuteAndHostMarkerFormatter
	{
		internal static string GetSelfMutePrefix()
		{
			string text = SanitizeColor(MuteAndHostMarkerPlugin.SelfMuteMarkerColorConfig.Value, "#FF0000");
			string text2 = EscapeTmpText(MuteAndHostMarkerPlugin.SelfMuteMarkerTextConfig.Value);
			return "<color=" + text + ">" + text2 + "</color>";
		}

		internal static string GetHostPrefix()
		{
			string text = SanitizeColor(MuteAndHostMarkerPlugin.HostMarkerColorConfig.Value, "#FFD700");
			string text2 = EscapeTmpText(MuteAndHostMarkerPlugin.HostMarkerTextConfig.Value);
			int num = Mathf.Clamp(MuteAndHostMarkerPlugin.HostMarkerSizePercentConfig.Value, 50, 300);
			return "<size=" + num + "%><color=" + text + ">" + text2 + "</color></size>";
		}

		internal static string StripOwnDecorations(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return string.Empty;
			}
			string text2 = text;
			string selfMutePrefix = GetSelfMutePrefix();
			string hostPrefix = GetHostPrefix();
			bool flag = true;
			int num = 0;
			while (flag && num < 10)
			{
				flag = false;
				num++;
				if (text2.StartsWith(hostPrefix + " ", StringComparison.Ordinal))
				{
					text2 = text2.Substring((hostPrefix + " ").Length);
					flag = true;
				}
				else if (text2.StartsWith(hostPrefix, StringComparison.Ordinal))
				{
					text2 = text2.Substring(hostPrefix.Length).TrimStart();
					flag = true;
				}
				if (text2.StartsWith(selfMutePrefix + " ", StringComparison.Ordinal))
				{
					text2 = text2.Substring((selfMutePrefix + " ").Length);
					flag = true;
				}
				else if (text2.StartsWith(selfMutePrefix, StringComparison.Ordinal))
				{
					text2 = text2.Substring(selfMutePrefix.Length).TrimStart();
					flag = true;
				}
				if (text2.StartsWith("<s>", StringComparison.Ordinal) && text2.EndsWith("</s>", StringComparison.Ordinal) && text2.Length >= 7)
				{
					text2 = text2.Substring(3, text2.Length - 7);
					flag = true;
				}
			}
			return text2;
		}

		private static string EscapeTmpText(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			return value.Replace("<", "<").Replace(">", ">");
		}

		private static string SanitizeColor(string value, string fallback)
		{
			if (string.IsNullOrEmpty(value))
			{
				return fallback;
			}
			string text = value.Trim();
			if (!text.StartsWith("#", StringComparison.Ordinal))
			{
				return fallback;
			}
			if (text.Length != 7 && text.Length != 9)
			{
				return fallback;
			}
			for (int i = 1; i < text.Length; i++)
			{
				char c = text[i];
				if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
				{
					return fallback;
				}
			}
			return text;
		}
	}
	internal static class ReflectionCache
	{
		private static readonly FieldInfo PlayerAvatarPlayerNameField = AccessTools.Field(typeof(PlayerAvatar), "playerName");

		private static readonly FieldInfo PlayerAvatarSteamIdField = AccessTools.Field(typeof(PlayerAvatar), "steamID");

		private static readonly FieldInfo PlayerAvatarIsLocalField = AccessTools.Field(typeof(PlayerAvatar), "isLocal");

		private static readonly FieldInfo PlayerAvatarVoiceChatField = AccessTools.Field(typeof(PlayerAvatar), "voiceChat");

		private static readonly FieldInfo PlayerVoiceChatPlayerAvatarField = AccessTools.Field(typeof(PlayerVoiceChat), "playerAvatar");

		private static readonly FieldInfo PlayerAvatarWorldNameField = AccessTools.Field(typeof(PlayerAvatar), "worldSpaceUIPlayerName");

		private static readonly FieldInfo PlayerVoiceChatToggleMuteField = AccessTools.Field(typeof(PlayerVoiceChat), "toggleMute");

		private static readonly FieldInfo WorldNamePlayerAvatarField = AccessTools.Field(typeof(WorldSpaceUIPlayerName), "playerAvatar");

		private static readonly FieldInfo MenuPlayerListedAvatarField = AccessTools.Field(typeof(MenuPlayerListed), "playerAvatar");

		private static readonly FieldInfo MenuSliderPlayerAvatarField = AccessTools.Field(typeof(MenuSliderPlayerMicGain), "playerAvatar");

		private static readonly FieldInfo MenuSliderField = AccessTools.Field(typeof(MenuSliderPlayerMicGain), "menuSlider");

		private static readonly FieldInfo MenuPageEscSlidersField = AccessTools.Field(typeof(MenuPageEsc), "playerMicGainSliders");

		private static readonly FieldInfo MenuPageLobbyListObjectsField = AccessTools.Field(typeof(MenuPageLobby), "listObjects");

		internal static string GetAvatarPlayerName(PlayerAvatar avatar)
		{
			object fieldValue = GetFieldValue(PlayerAvatarPlayerNameField, avatar);
			return fieldValue as string;
		}

		internal static string GetAvatarSteamId(PlayerAvatar avatar)
		{
			object fieldValue = GetFieldValue(PlayerAvatarSteamIdField, avatar);
			return fieldValue as string;
		}

		internal static bool GetAvatarIsLocal(PlayerAvatar avatar)
		{
			if (!(GetFieldValue(PlayerAvatarIsLocalField, avatar) is bool result))
			{
				return false;
			}
			return result;
		}

		internal static PlayerVoiceChat GetAvatarVoiceChat(PlayerAvatar avatar)
		{
			object fieldValue = GetFieldValue(PlayerAvatarVoiceChatField, avatar);
			return (PlayerVoiceChat)((fieldValue is PlayerVoiceChat) ? fieldValue : null);
		}

		internal static WorldSpaceUIPlayerName GetWorldSpaceUIPlayerName(PlayerAvatar avatar)
		{
			object fieldValue = GetFieldValue(PlayerAvatarWorldNameField, avatar);
			return (WorldSpaceUIPlayerName)((fieldValue is WorldSpaceUIPlayerName) ? fieldValue : null);
		}

		internal static PlayerAvatar GetWorldNamePlayerAvatar(WorldSpaceUIPlayerName worldName)
		{
			object fieldValue = GetFieldValue(WorldNamePlayerAvatarField, worldName);
			return (PlayerAvatar)((fieldValue is PlayerAvatar) ? fieldValue : null);
		}

		internal static PlayerAvatar GetVoiceChatPlayerAvatar(PlayerVoiceChat voiceChat)
		{
			object fieldValue = GetFieldValue(PlayerVoiceChatPlayerAvatarField, voiceChat);
			return (PlayerAvatar)((fieldValue is PlayerAvatar) ? fieldValue : null);
		}

		internal static bool GetVoiceChatToggleMute(PlayerVoiceChat voiceChat)
		{
			if (!(GetFieldValue(PlayerVoiceChatToggleMuteField, voiceChat) is bool result))
			{
				return false;
			}
			return result;
		}

		internal static PlayerAvatar GetMenuPlayerListedAvatar(MenuPlayerListed listed)
		{
			object fieldValue = GetFieldValue(MenuPlayerListedAvatarField, listed);
			return (PlayerAvatar)((fieldValue is PlayerAvatar) ? fieldValue : null);
		}

		internal static PlayerAvatar GetMenuSliderPlayerAvatar(MenuSliderPlayerMicGain slider)
		{
			object fieldValue = GetFieldValue(MenuSliderPlayerAvatarField, slider);
			return (PlayerAvatar)((fieldValue is PlayerAvatar) ? fieldValue : null);
		}

		internal static TMP_Text GetMenuSliderNameText(MenuSliderPlayerMicGain slider, PlayerAvatar avatar)
		{
			object fieldValue = GetFieldValue(MenuSliderField, slider);
			MenuSlider val = (MenuSlider)((fieldValue is MenuSlider) ? fieldValue : null);
			if ((Object)(object)val == (Object)null && (Object)(object)slider != (Object)null)
			{
				val = ((Component)slider).GetComponent<MenuSlider>();
			}
			if ((Object)(object)val == (Object)null || (Object)(object)slider == (Object)null)
			{
				return null;
			}
			TMP_Text elementNameText = (TMP_Text)(object)val.elementNameText;
			if (IsEscNameTextCandidate(val, elementNameText, avatar))
			{
				return elementNameText;
			}
			TMP_Text[] componentsInChildren = ((Component)slider).GetComponentsInChildren<TMP_Text>(true);
			if (componentsInChildren == null)
			{
				return null;
			}
			string avatarPlayerName = GetAvatarPlayerName(avatar);
			foreach (TMP_Text val2 in componentsInChildren)
			{
				if (IsEscNameTextCandidate(val, val2, avatar))
				{
					string text = MuteAndHostMarkerFormatter.StripOwnDecorations(val2.text ?? string.Empty);
					if (!string.IsNullOrEmpty(avatarPlayerName) && text == avatarPlayerName)
					{
						return val2;
					}
				}
			}
			return null;
		}

		private static bool IsEscNameTextCandidate(MenuSlider menuSlider, TMP_Text candidate, PlayerAvatar avatar)
		{
			if ((Object)(object)menuSlider == (Object)null || (Object)(object)candidate == (Object)null || (Object)(object)avatar == (Object)null)
			{
				return false;
			}
			if ((Object)(object)menuSlider.segmentText != (Object)null && (Object)(object)candidate == (Object)(object)menuSlider.segmentText)
			{
				return false;
			}
			if ((Object)(object)menuSlider.segmentMaskText != (Object)null && (Object)(object)candidate == (Object)(object)menuSlider.segmentMaskText)
			{
				return false;
			}
			string text = candidate.text ?? string.Empty;
			string text2 = MuteAndHostMarkerFormatter.StripOwnDecorations(text);
			string avatarPlayerName = GetAvatarPlayerName(avatar);
			if (string.IsNullOrEmpty(avatarPlayerName))
			{
				return false;
			}
			if (text2 == avatarPlayerName)
			{
				return true;
			}
			string text3 = menuSlider.elementName ?? string.Empty;
			if (text3 == avatarPlayerName && text == avatarPlayerName)
			{
				return true;
			}
			return false;
		}

		internal static Dictionary<PlayerAvatar, MenuSliderPlayerMicGain> GetEscSliders(MenuPageEsc page)
		{
			return GetFieldValue(MenuPageEscSlidersField, page) as Dictionary<PlayerAvatar, MenuSliderPlayerMicGain>;
		}

		internal static List<GameObject> GetLobbyListObjects(MenuPageLobby page)
		{
			return GetFieldValue(MenuPageLobbyListObjectsField, page) as List<GameObject>;
		}

		private static object GetFieldValue(FieldInfo field, object instance)
		{
			if (field == null || instance == null)
			{
				return null;
			}
			try
			{
				return field.GetValue(instance);
			}
			catch
			{
				return null;
			}
		}
	}
	internal static class MuteAndHostMarkerPatches
	{
		[HarmonyPatch(typeof(WorldSpaceUIParent), "PlayerName")]
		[HarmonyPostfix]
		private static void WorldSpaceUIParent_PlayerName_Postfix(PlayerAvatar _player)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyWorldName(_player);
			}
			catch (Exception ex)
			{
				LogError("Failure: WorldSpaceUIParent.PlayerName Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(WorldSpaceUIPlayerName), "Update")]
		[HarmonyPostfix]
		private static void WorldSpaceUIPlayerName_Update_Postfix(WorldSpaceUIPlayerName __instance)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyWorldNameComponent(__instance);
			}
			catch (Exception ex)
			{
				LogError("Failure: WorldSpaceUIPlayerName.Update Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(MenuPageLobby), "Update")]
		[HarmonyPostfix]
		private static void MenuPageLobby_Update_Postfix(MenuPageLobby __instance)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyMenuPageLobby(__instance);
			}
			catch (Exception ex)
			{
				LogError("Failure: MenuPageLobby.Update Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(MenuPageEsc), "PlayerGainSlidersUpdate")]
		[HarmonyPostfix]
		private static void MenuPageEsc_PlayerGainSlidersUpdate_Postfix(MenuPageEsc __instance)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyMenuPageEsc(__instance);
			}
			catch (Exception ex)
			{
				LogError("Failure: MenuPageEsc.PlayerGainSlidersUpdate Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(MenuSliderPlayerMicGain), "SliderNameSet")]
		[HarmonyPostfix]
		private static void MenuSliderPlayerMicGain_SliderNameSet_Postfix(MenuSliderPlayerMicGain __instance)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyEscSlider(__instance);
			}
			catch (Exception ex)
			{
				LogError("Failure: MenuSliderPlayerMicGain.SliderNameSet Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(MenuSliderPlayerMicGain), "Update")]
		[HarmonyPostfix]
		private static void MenuSliderPlayerMicGain_Update_Postfix(MenuSliderPlayerMicGain __instance)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyEscSlider(__instance);
			}
			catch (Exception ex)
			{
				LogError("Failure: MenuSliderPlayerMicGain.Update Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(MenuPlayerListed), "Update")]
		[HarmonyPostfix]
		private static void MenuPlayerListed_Update_Postfix(MenuPlayerListed __instance)
		{
			try
			{
				MuteAndHostMarkerApplier.ApplyLobbyListed(__instance);
			}
			catch (Exception ex)
			{
				LogError("Failure: MenuPlayerListed.Update Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(PlayerVoiceChat), "ToggleMuteRPC")]
		[HarmonyPostfix]
		private static void PlayerVoiceChat_ToggleMuteRPC_Postfix(PlayerVoiceChat __instance)
		{
			try
			{
				PlayerAvatar voiceChatPlayerAvatar = ReflectionCache.GetVoiceChatPlayerAvatar(__instance);
				MuteAndHostMarkerApplier.RefreshKnownTargetsForAvatar(voiceChatPlayerAvatar);
			}
			catch (Exception ex)
			{
				LogError("Failure: PlayerVoiceChat.ToggleMuteRPC Postfix\n" + ex);
			}
		}

		[HarmonyPatch(typeof(GameManager), "PlayerMicrophoneSettingSet")]
		[HarmonyPostfix]
		private static void GameManager_PlayerMicrophoneSettingSet_Postfix(string _name)
		{
			try
			{
				MuteAndHostMarkerApplier.RefreshKnownTargetsBySteamId(_name);
			}
			catch (Exception ex)
			{
				LogError("Failure: GameManager.PlayerMicrophoneSettingSet Postfix\n" + ex);
			}
		}

		private static void LogError(string message)
		{
			if (MuteAndHostMarkerPlugin.Log != null)
			{
				MuteAndHostMarkerPlugin.Log.LogError((object)message);
			}
		}
	}
}