Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MuteAndHostMarker v4.0.0
MuteAndHostMarker.dll
Decompiled 17 hours agousing 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); } } } }