using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MicMute")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MicMute")]
[assembly: AssemblyTitle("MicMute")]
[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 MicMute
{
internal class Mute : MonoBehaviour
{
[HarmonyPatch(typeof(Megaphone), "OnUseStart")]
private static class NoTalkingWhileMuted
{
[HarmonyPriority(800)]
private static bool Prefix(Megaphone __instance)
{
if (Plugin.Muted.Value)
{
return !((NetworkBehaviour)__instance).isOwned;
}
return true;
}
}
[HarmonyPatch]
private static class SilenceMicrophone
{
private static MethodBase TargetMethod()
{
return AccessTools.Method("Dissonance.Audio.Capture.BasePreprocessingPipeline:SendSamplesToSubscribers", (Type[])null, (Type[])null);
}
private static void Prefix(float[] buffer)
{
if (silenced && buffer != null)
{
Array.Clear(buffer, 0, buffer.Length);
}
}
}
[HarmonyPatch]
private static class NotSpeakingWhileMuted
{
private static MethodBase TargetMethod()
{
return AccessTools.PropertyGetter(typeof(DissonanceComms).Assembly.GetType("Dissonance.LocalVoicePlayerState"), "IsSpeaking");
}
private static void Postfix(ref bool __result)
{
if (silenced)
{
__result = false;
}
}
}
private const string LobbyKey = "cmm_muted";
private PlayerInputActions input;
private InputAction action;
private DissonanceComms comms;
private DissonanceComms appliedTo;
private bool appliedValue;
private float nextCommsSearch;
private string published;
private static volatile bool silenced;
private static readonly FieldRef<Megaphone, bool> Talking = AccessTools.FieldRefAccess<Megaphone, bool>("predictedActive");
public static bool IsMuted(Player player)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
return false;
}
if ((Object)(object)player == (Object)(object)Player.Local)
{
return Plugin.Muted.Value;
}
PlayerController playerController = player.playerController;
CSteamID val = CurrentLobby();
if ((Object)(object)playerController == (Object)null || playerController.steamId == 0L || !((CSteamID)(ref val)).IsValid())
{
return false;
}
CSteamID val2 = default(CSteamID);
((CSteamID)(ref val2))..ctor(playerController.steamId);
return SteamMatchmaking.GetLobbyMemberData(val, val2, "cmm_muted") == "1";
}
private static CSteamID CurrentLobby()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
if (!SteamManager.Initialized || (Object)(object)SteamLobby.instance == (Object)null)
{
return CSteamID.Nil;
}
return SteamLobby.instance.currentLobbyID;
}
private void Update()
{
ListenForKey();
if (Plugin.Muted.Value && !silenced)
{
StopTalking();
}
silenced = Plugin.Muted.Value;
ApplyToVoiceChat();
Publish();
}
private static void StopTalking()
{
Megaphone[] array = Object.FindObjectsByType<Megaphone>((FindObjectsSortMode)0);
foreach (Megaphone val in array)
{
if (((NetworkBehaviour)val).isOwned && Talking.Invoke(val))
{
((HeldItem)val).OnUseStop();
}
}
}
private void ListenForKey()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
if (action == null)
{
if ((Object)(object)SettingsManager.instance == (Object)null)
{
return;
}
input = new PlayerInputActions();
InputRebinding.Register(input.asset);
action = input.asset.FindAction("MuteMic", false);
if (action == null)
{
return;
}
action.Enable();
}
if (action.WasPressedThisFrame() && !((Object)(object)Player.Local == (Object)null) && !KeybindPanel.IsRebinding && KeybindPanel.RebindEndedFrame != Time.frameCount && !Player.LocalStationClaims(action) && !Typing())
{
Plugin.Muted.Value = !Plugin.Muted.Value;
}
}
private static bool Typing()
{
GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
if ((Object)(object)val == (Object)null)
{
return false;
}
TMP_InputField component = val.GetComponent<TMP_InputField>();
if ((Object)(object)component != (Object)null && component.isFocused)
{
return true;
}
InputField component2 = val.GetComponent<InputField>();
if ((Object)(object)component2 != (Object)null)
{
return component2.isFocused;
}
return false;
}
private void ApplyToVoiceChat()
{
if ((Object)(object)comms == (Object)null && Time.unscaledTime >= nextCommsSearch)
{
comms = Object.FindFirstObjectByType<DissonanceComms>();
nextCommsSearch = Time.unscaledTime + 1f;
}
if (!((Object)(object)comms == (Object)null))
{
bool value = Plugin.Muted.Value;
if (!((Object)(object)comms == (Object)(object)appliedTo) || value != appliedValue)
{
comms.IsMuted = value;
appliedTo = comms;
appliedValue = value;
}
}
}
private void Publish()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
CSteamID val = CurrentLobby();
if (((CSteamID)(ref val)).IsValid())
{
string text = (Plugin.Muted.Value ? "1" : "");
string text2 = val.m_SteamID + ":" + text;
if (!(text2 == published))
{
SteamMatchmaking.SetLobbyMemberData(val, "cmm_muted", text);
published = text2;
}
}
}
private void OnDestroy()
{
if (input != null)
{
InputRebinding.Unregister(input.asset);
input.Dispose();
}
}
}
internal class MutedHud : MonoBehaviour
{
private const float AboveBottom = 118f;
private static readonly FieldRef<PlayerHUD, CanvasGroup> HudGroup = AccessTools.FieldRefAccess<PlayerHUD, CanvasGroup>("hudGroup");
private GameObject root;
private CanvasGroup group;
private GameObject badge;
private void Update()
{
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Player.Local == (Object)null)
{
if ((Object)(object)root != (Object)null)
{
root.SetActive(false);
}
return;
}
if ((Object)(object)root == (Object)null)
{
Build();
}
root.SetActive(true);
PlayerHUD instance = PlayerHUD.Instance;
CanvasGroup val = (((Object)(object)instance != (Object)null) ? HudGroup.Invoke(instance) : null);
group.alpha = (((Object)(object)val != (Object)null) ? val.alpha : 1f);
badge.SetActive(Plugin.Muted.Value);
badge.transform.localScale = Vector3.one * Plugin.HudScale.Value;
}
private void Build()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Expected O, but got Unknown
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0208: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_0274: Unknown result type (might be due to invalid IL or missing references)
//IL_0279: Unknown result type (might be due to invalid IL or missing references)
//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
root = new GameObject("MicMute_HUD");
Object.DontDestroyOnLoad((Object)(object)root);
Canvas obj = root.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 400;
CanvasScaler obj2 = root.AddComponent<CanvasScaler>();
obj2.uiScaleMode = (ScaleMode)1;
obj2.referenceResolution = new Vector2(1920f, 1080f);
obj2.matchWidthOrHeight = 1f;
group = root.AddComponent<CanvasGroup>();
group.blocksRaycasts = false;
group.interactable = false;
badge = new GameObject("Muted", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
RectTransform val = (RectTransform)badge.transform;
((Transform)val).SetParent(root.transform, false);
val.anchorMin = new Vector2(0.5f, 0f);
val.anchorMax = new Vector2(0.5f, 0f);
val.pivot = new Vector2(0.5f, 0f);
val.anchoredPosition = new Vector2(0f, 118f);
Image component = badge.GetComponent<Image>();
((Graphic)component).color = new Color(0f, 0f, 0f, 0.45f);
((Graphic)component).raycastTarget = false;
HorizontalLayoutGroup obj3 = badge.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)obj3).padding = new RectOffset(10, 14, 4, 4);
((HorizontalOrVerticalLayoutGroup)obj3).spacing = 8f;
((LayoutGroup)obj3).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
ContentSizeFitter obj4 = badge.AddComponent<ContentSizeFitter>();
obj4.horizontalFit = (FitMode)2;
obj4.verticalFit = (FitMode)2;
GameObject val2 = new GameObject("Icon", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val2.transform.SetParent(badge.transform, false);
Image component2 = val2.GetComponent<Image>();
component2.sprite = Icons.MicOff;
((Graphic)component2).color = Icons.Red;
component2.preserveAspect = true;
((Graphic)component2).raycastTarget = false;
((Behaviour)component2).enabled = (Object)(object)Icons.MicOff != (Object)null;
LayoutElement obj5 = val2.AddComponent<LayoutElement>();
obj5.preferredWidth = 34f;
obj5.preferredHeight = 34f;
GameObject val3 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
val3.transform.SetParent(badge.transform, false);
TextMeshProUGUI obj6 = val3.AddComponent<TextMeshProUGUI>();
PlayerHUD instance = PlayerHUD.Instance;
TMP_Text val4 = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInChildren<TMP_Text>(true) : null);
((TMP_Text)obj6).font = (((Object)(object)val4 != (Object)null) ? val4.font : TMP_Settings.defaultFontAsset);
((TMP_Text)obj6).text = "MUTED";
((Graphic)obj6).color = Icons.Red;
((TMP_Text)obj6).fontSize = 30f;
((TMP_Text)obj6).textWrappingMode = (TextWrappingModes)0;
((Graphic)obj6).raycastTarget = false;
}
}
internal static class MuteKey
{
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static class AddAction
{
private static void Postfix(PlayerInputActions __instance)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
InputActionMap val = __instance.asset.FindActionMap("Gameplay", false);
if (val != null && val.FindAction("MuteMic", false) == null)
{
InputAction obj = InputActionSetupExtensions.AddAction(val, "MuteMic", (InputActionType)1, (string)null, (string)null, (string)null, (string)null, (string)null);
InputBinding val2 = default(InputBinding);
((InputBinding)(ref val2)).path = "<Keyboard>/m";
((InputBinding)(ref val2)).groups = "Keyboard&Mouse";
((InputBinding)(ref val2)).id = BindingId;
InputActionSetupExtensions.AddBinding(obj, val2);
}
}
}
[HarmonyPatch(typeof(LocalizationManager), "Get")]
private static class Name
{
private static bool Prefix(string key, ref string __result)
{
if (key != "Keybind_MuteMic")
{
return true;
}
__result = "Mute Mic";
return false;
}
}
public const string ActionName = "MuteMic";
public const string LabelKey = "Keybind_MuteMic";
public const string Label = "Mute Mic";
public static readonly Guid BindingId = new Guid("5f0d6c0e-3b7a-4c8e-9a51-2d64b8e1f0a7");
public static void Install()
{
FieldInfo fieldInfo = AccessTools.Field(typeof(KeybindPanel), "Entries");
Type nestedType = typeof(KeybindPanel).GetNestedType("RebindEntry", BindingFlags.NonPublic);
Type nestedType2 = typeof(KeybindPanel).GetNestedType("Devices", BindingFlags.NonPublic);
if (fieldInfo == null || nestedType == null || nestedType2 == null)
{
Plugin.Log.LogWarning((object)"Couldn't add Mute Mic to the Controls screen; M still works");
return;
}
Array array = (Array)fieldInfo.GetValue(null);
object obj = Enum.ToObject(nestedType2, 1);
object value = Activator.CreateInstance(nestedType, "MuteMic", "", "Keybind_MuteMic", obj);
int num = array.Length;
for (int i = 0; i < array.Length; i++)
{
string text = (string)AccessTools.Field(nestedType, "actionName").GetValue(array.GetValue(i));
if (text == "MuteMic")
{
return;
}
if (text == "PushToTalk")
{
num = i + 1;
}
}
Array array2 = Array.CreateInstance(nestedType, array.Length + 1);
Array.Copy(array, 0, array2, 0, num);
array2.SetValue(value, num);
Array.Copy(array, num, array2, num + 1, array.Length - num);
fieldInfo.SetValue(null, array2);
}
}
internal class MutedBadge : MonoBehaviour
{
private static readonly FieldRef<PlayerNameplate, CanvasGroup> SpeakingIcon = AccessTools.FieldRefAccess<PlayerNameplate, CanvasGroup>("speakingIcon");
private static readonly FieldRef<PlayerNameplate, Player> Owner = AccessTools.FieldRefAccess<PlayerNameplate, Player>("_player");
private PlayerNameplate plate;
private GameObject speaking;
private GameObject badge;
private float nextCheck;
private void Start()
{
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
plate = ((Component)this).GetComponent<PlayerNameplate>();
CanvasGroup val = (((Object)(object)plate != (Object)null) ? SpeakingIcon.Invoke(plate) : null);
if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)(object)((Component)this).gameObject || (Object)(object)Icons.MicOff == (Object)null)
{
((Behaviour)this).enabled = false;
return;
}
speaking = ((Component)val).gameObject;
badge = Object.Instantiate<GameObject>(speaking, speaking.transform.parent, false);
((Object)badge).name = "MutedIcon";
CanvasGroup component = badge.GetComponent<CanvasGroup>();
if ((Object)(object)component != (Object)null)
{
component.alpha = 1f;
}
Image[] componentsInChildren = badge.GetComponentsInChildren<Image>(true);
if (componentsInChildren.Length != 0)
{
Image obj = componentsInChildren[^1];
obj.sprite = Icons.MicOff;
((Graphic)obj).color = Icons.Red;
obj.preserveAspect = true;
}
badge.SetActive(false);
}
private void LateUpdate()
{
if (!(Time.unscaledTime < nextCheck))
{
nextCheck = Time.unscaledTime + 0.25f;
bool flag = Plugin.ShowOthersMuted.Value && Mute.IsMuted(Owner.Invoke(plate));
if (badge.activeSelf != flag)
{
badge.SetActive(flag);
speaking.SetActive(!flag);
}
}
}
}
[HarmonyPatch(typeof(PlayerNameplate), "Awake")]
internal static class NameplateAwake
{
private static void Postfix(PlayerNameplate __instance)
{
if ((Object)(object)((Component)__instance).GetComponent<MutedBadge>() == (Object)null)
{
((Component)__instance).gameObject.AddComponent<MutedBadge>();
}
}
}
[BepInPlugin("crackmodsui.micmute", "Mic Mute", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "crackmodsui.micmute";
public const string Name = "Mic Mute";
public const string Version = "0.1.0";
internal static ManualLogSource Log;
internal static ConfigEntry<bool> Muted;
internal static ConfigEntry<bool> ShowOthersMuted;
internal static ConfigEntry<float> HudScale;
private void Awake()
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_0097: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Muted = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Muted", false, "Your mic is muted: nothing you say is sent. Toggle it with Mute Mic in the game's Controls settings (M by default). Kept between sessions.");
HudScale = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Scale", 1f, new ConfigDescription("Size of the MUTED badge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
ShowOthersMuted = ((BaseUnityPlugin)this).Config.Bind<bool>("Nameplates", "ShowOthersMuted", true, "Show a muted icon over the nameplates of players who muted themselves with this mod.");
Icons.Load();
MuteKey.Install();
new Harmony("crackmodsui.micmute").PatchAll(typeof(Plugin).Assembly);
GameObject val = new GameObject("MicMute")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<Mute>();
val.AddComponent<MutedHud>();
Log.LogInfo((object)"Mic Mute 0.1.0 loaded");
}
}
internal static class Icons
{
public static readonly Color Red = new Color(0.94f, 0.33f, 0.31f);
public static Sprite MicOff;
public static void Load()
{
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Expected O, but got Unknown
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
byte[] array;
using (Stream stream = typeof(Icons).Assembly.GetManifestResourceStream("micoff.alpha"))
{
if (stream == null)
{
return;
}
array = new byte[stream.Length];
for (int i = 0; i < array.Length; i += stream.Read(array, i, array.Length - i))
{
}
}
int num = array[0] | (array[1] << 8);
int num2 = array[2] | (array[3] << 8);
if (array.Length == 4 + num * num2)
{
Color32[] array2 = (Color32[])(object)new Color32[num * num2];
for (int j = 0; j < array2.Length; j++)
{
array2[j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, array[4 + j]);
}
Texture2D val = new Texture2D(num, num2, (TextureFormat)4, true)
{
name = "MicMute_MicOff",
wrapMode = (TextureWrapMode)1
};
val.SetPixels32(array2);
val.Apply(true, true);
Object.DontDestroyOnLoad((Object)val);
MicOff = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), 100f);
((Object)MicOff).name = "MicMute_MicOff";
Object.DontDestroyOnLoad((Object)(object)MicOff);
}
}
}
}