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 VoiceFix v1.0.1
VoiceFixMod.dll
Decompiled 8 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("VoiceFixMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("My first plugin")] [assembly: AssemblyTitle("VoiceFixMod")] [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 VoiceFixMod { [BepInPlugin("com.Kingo.voicefix", "VoiceFixMod", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "com.Kingo.voicefix"; public const string Name = "VoiceFixMod"; public const string Version = "1.0.0"; internal static ManualLogSource LogS; private Harmony _harmony; private static ConfigEntry<float> _silenceSecondsBeforeReinit; private static ConfigEntry<float> _keepAliveEverySeconds; private static ConfigEntry<float> _reinitCooldownSeconds; private static ConfigEntry<bool> _enableAutoReinit; private static ConfigEntry<bool> _enableKeepAlive; private static ConfigEntry<bool> _verboseLogs; private static ConfigEntry<KeyCode> _forceReinitKey; private VoiceFixController _controller; private GameObject _controllerGO; private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) LogS = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("com.Kingo.voicefix"); _harmony.PatchAll(); _silenceSecondsBeforeReinit = ((BaseUnityPlugin)this).Config.Bind<float>("Watchdog", "SilenceSecondsBeforeReinit", 35f, "If no inbound voice is heard for this many seconds, re-initialize voice."); _keepAliveEverySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Watchdog", "KeepAliveEverySeconds", 8f, "How often to send a tiny keep-alive (quick mic toggle) to prevent idle timeouts."); _reinitCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Watchdog", "ReinitCooldownSeconds", 20f, "Minimum time between automatic re-inits."); _enableAutoReinit = ((BaseUnityPlugin)this).Config.Bind<bool>("Watchdog", "EnableAutoReinit", true, "Automatically re-initialize voice when silence threshold is reached."); _enableKeepAlive = ((BaseUnityPlugin)this).Config.Bind<bool>("Watchdog", "EnableKeepAlive", true, "Periodically nudge the voice backend so it doesn't sleep."); _verboseLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogs", false, "Extra debug logs."); _forceReinitKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "ForceReinitKey", (KeyCode)291, "Hold LeftShift + press this key to force a voice re-init."); _controllerGO = new GameObject("VoiceFixMod_Controller"); _controller = _controllerGO.AddComponent<VoiceFixController>(); _controller.Init(_silenceSecondsBeforeReinit.Value, _keepAliveEverySeconds.Value, _reinitCooldownSeconds.Value, _enableAutoReinit.Value, _enableKeepAlive.Value, _verboseLogs.Value, _forceReinitKey.Value); Object.DontDestroyOnLoad((Object)(object)_controllerGO); LogS.LogInfo((object)("VoiceFixMod 1.0.0 loaded. GameRoot: " + Paths.GameRootPath)); } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } if (!((Object)(object)_controller != (Object)null)) { return; } try { Object.Destroy((Object)(object)_controller); } catch { } try { if (Object.op_Implicit((Object)(object)_controllerGO)) { Object.Destroy((Object)(object)_controllerGO); } } catch { } } } internal class VoiceFixController : MonoBehaviour { [CompilerGenerated] private sealed class <LateStart>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public VoiceFixController <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LateStart>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.DiscoverBackend(); <>4__this.AttachAudioTaps(); <>4__this._inited = true; Plugin.LogS.LogInfo((object)"[VoiceFix] Initialization complete."); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ReinitializeVoice>d__25 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string reason; public VoiceFixController <>4__this; private Behaviour[] <comps>5__1; private Behaviour[] <>s__2; private int <>s__3; private Behaviour <comp>5__4; private Type <t>5__5; private bool <invokedAny>5__6; private bool <needDelay>5__7; private string[] <tries>5__8; private string[] <>s__9; private int <>s__10; private string <name>5__11; private MethodInfo <m>5__12; private Exception <ex>5__13; private Exception <ex>5__14; private bool <disabled>5__15; private Exception <ex>5__16; private Exception <ex>5__17; private int <i>5__18; private AudioActivityTap <tap>5__19; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ReinitializeVoice>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <comps>5__1 = null; <>s__2 = null; <comp>5__4 = null; <t>5__5 = null; <tries>5__8 = null; <>s__9 = null; <name>5__11 = null; <m>5__12 = null; <ex>5__13 = null; <ex>5__14 = null; <ex>5__16 = null; <ex>5__17 = null; <tap>5__19 = null; <>1__state = -2; } private bool MoveNext() { //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Expected O, but got Unknown //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Expected O, but got Unknown //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this._lastReinit = Time.realtimeSinceStartup; Plugin.LogS.LogWarning((object)("[VoiceFix] Re-initializing voice (" + reason + ").")); <comps>5__1 = (Behaviour[])(object)new Behaviour[3] { <>4__this._dissonanceComms, <>4__this._vivoxMgr, <>4__this._genericVoiceMgr }; <>s__2 = <comps>5__1; <>s__3 = 0; goto IL_045d; case 1: <>1__state = -1; goto IL_0372; case 2: <>1__state = -1; try { <comp>5__4.enabled = true; } catch (Exception ex) { <ex>5__17 = ex; Plugin.LogS.LogWarning((object)("[VoiceFix] Soft-enable failed: " + <ex>5__17.Message)); } goto IL_0440; case 3: { <>1__state = -1; <>4__this.AttachAudioTaps(); <>4__this._lastHeardTime = Time.realtimeSinceStartup; Plugin.LogS.LogInfo((object)"[VoiceFix] Voice re-init attempt complete."); return false; } IL_045d: if (<>s__3 < <>s__2.Length) { <comp>5__4 = <>s__2[<>s__3]; if ((Object)(object)<comp>5__4 == (Object)null) { goto IL_044f; } <t>5__5 = ((object)<comp>5__4).GetType(); <invokedAny>5__6 = false; <needDelay>5__7 = false; try { <tries>5__8 = new string[10] { "Reset", "Reinit", "ReInitialize", "Initialize", "Init", "Shutdown", "Stop", "Start", "Login", "Reconnect" }; <>s__9 = <tries>5__8; for (<>s__10 = 0; <>s__10 < <>s__9.Length; <>s__10++) { <name>5__11 = <>s__9[<>s__10]; <m>5__12 = <t>5__5.GetMethod(<name>5__11, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if ((object)<m>5__12 != null) { if (<>4__this._verbose) { Plugin.LogS.LogDebug((object)("[VoiceFix] Calling " + <t>5__5.Name + "." + <name>5__11 + "()")); } try { <m>5__12.Invoke(<comp>5__4, null); <invokedAny>5__6 = true; if (<name>5__11.Equals("Shutdown", StringComparison.OrdinalIgnoreCase) || <name>5__11.Equals("Stop", StringComparison.OrdinalIgnoreCase)) { <needDelay>5__7 = true; } } catch (Exception ex) { <ex>5__13 = ex; Plugin.LogS.LogWarning((object)("[VoiceFix] " + <t>5__5.Name + "." + <name>5__11 + "() invocation failed: " + <ex>5__13.Message)); } } <m>5__12 = null; <name>5__11 = null; } <>s__9 = null; <tries>5__8 = null; } catch (Exception ex) { <ex>5__14 = ex; Plugin.LogS.LogWarning((object)("[VoiceFix] Reinit reflection on " + <t>5__5.FullName + " failed: " + <ex>5__14.Message)); } if (<needDelay>5__7) { <>2__current = (object)new WaitForSeconds(0.15f); <>1__state = 1; return true; } goto IL_0372; } <>s__2 = null; <i>5__18 = 0; while (<i>5__18 < <>4__this._taps.Count) { <tap>5__19 = <>4__this._taps[<i>5__18]; if (Object.op_Implicit((Object)(object)<tap>5__19)) { Object.Destroy((Object)(object)<tap>5__19); } <tap>5__19 = null; <i>5__18++; } <>4__this._taps.Clear(); <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 3; return true; IL_0440: <t>5__5 = null; <comp>5__4 = null; goto IL_044f; IL_0372: if (!<invokedAny>5__6) { <disabled>5__15 = false; try { <comp>5__4.enabled = false; <disabled>5__15 = true; } catch (Exception ex) { <ex>5__16 = ex; Plugin.LogS.LogWarning((object)("[VoiceFix] Soft-disable failed: " + <ex>5__16.Message)); } if (<disabled>5__15) { <>2__current = (object)new WaitForSeconds(0.05f); <>1__state = 2; return true; } } goto IL_0440; IL_044f: <>s__3++; goto IL_045d; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SendKeepAlive>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public VoiceFixController <>4__this; private bool <nudged>5__1; private Type <t>5__2; private PropertyInfo <prop>5__3; private object <currObj>5__4; private bool <curr>5__5; private bool <setOk>5__6; private Exception <ex>5__7; private Exception <ex>5__8; private Exception <ex>5__9; private bool <disabled>5__10; private Exception <ex>5__11; private Exception <ex>5__12; private bool <disabled>5__13; private Exception <ex>5__14; private Exception <ex>5__15; private bool <disabled>5__16; private Exception <ex>5__17; private Exception <ex>5__18; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SendKeepAlive>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <t>5__2 = null; <prop>5__3 = null; <currObj>5__4 = null; <ex>5__7 = null; <ex>5__8 = null; <ex>5__9 = null; <ex>5__11 = null; <ex>5__12 = null; <ex>5__14 = null; <ex>5__15 = null; <ex>5__17 = null; <ex>5__18 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (<>4__this._verbose) { Plugin.LogS.LogDebug((object)"[VoiceFix] Keep-alive tick."); } <nudged>5__1 = false; if ((Object)(object)<>4__this._dissonanceComms != (Object)null) { <t>5__2 = ((object)<>4__this._dissonanceComms).GetType(); <prop>5__3 = <>4__this.FindFirstProperty(<t>5__2, new string[5] { "IsMuted", "IsMicMuted", "Muted", "isMuted", "muted" }); if ((object)<prop>5__3 != null) { <currObj>5__4 = null; try { <currObj>5__4 = <prop>5__3.GetValue(<>4__this._dissonanceComms, null); } catch (Exception ex) { <ex>5__7 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] prop.GetValue failed: " + <ex>5__7.Message)); } <curr>5__5 = <>4__this.SafeConvertToBool(<currObj>5__4, fallback: false); <setOk>5__6 = false; try { <prop>5__3.SetValue(<>4__this._dissonanceComms, !<curr>5__5, null); <setOk>5__6 = true; } catch (Exception ex) { <ex>5__8 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] prop.SetValue failed (set): " + <ex>5__8.Message)); } if (<setOk>5__6) { <>2__current = null; <>1__state = 1; return true; } goto IL_0243; } <disabled>5__10 = false; try { <>4__this._dissonanceComms.enabled = false; <disabled>5__10 = true; } catch (Exception ex) { <ex>5__11 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] Dissonance disable failed: " + <ex>5__11.Message)); } if (<disabled>5__10) { <>2__current = null; <>1__state = 2; return true; } goto IL_0314; } if ((Object)(object)<>4__this._vivoxMgr != (Object)null) { <disabled>5__13 = false; try { <>4__this._vivoxMgr.enabled = false; <disabled>5__13 = true; } catch (Exception ex) { <ex>5__14 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] Vivox disable failed: " + <ex>5__14.Message)); } if (<disabled>5__13) { <>2__current = null; <>1__state = 3; return true; } } else if ((Object)(object)<>4__this._genericVoiceMgr != (Object)null) { <disabled>5__16 = false; try { <>4__this._genericVoiceMgr.enabled = false; <disabled>5__16 = true; } catch (Exception ex) { <ex>5__17 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] Generic disable failed: " + <ex>5__17.Message)); } if (<disabled>5__16) { <>2__current = null; <>1__state = 4; return true; } } break; case 1: <>1__state = -1; try { <prop>5__3.SetValue(<>4__this._dissonanceComms, <curr>5__5, null); <nudged>5__1 = true; } catch (Exception ex) { <ex>5__9 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] prop.SetValue failed (restore): " + <ex>5__9.Message)); } goto IL_0243; case 2: <>1__state = -1; try { <>4__this._dissonanceComms.enabled = true; <nudged>5__1 = true; } catch (Exception ex) { <ex>5__12 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] Dissonance enable failed: " + <ex>5__12.Message)); } goto IL_0314; case 3: <>1__state = -1; try { <>4__this._vivoxMgr.enabled = true; <nudged>5__1 = true; } catch (Exception ex) { <ex>5__15 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] Vivox enable failed: " + <ex>5__15.Message)); } break; case 4: { <>1__state = -1; try { <>4__this._genericVoiceMgr.enabled = true; <nudged>5__1 = true; } catch (Exception ex) { <ex>5__18 = ex; Plugin.LogS.LogDebug((object)("[VoiceFix] Generic enable failed: " + <ex>5__18.Message)); } break; } IL_0314: <t>5__2 = null; <prop>5__3 = null; break; IL_0243: <currObj>5__4 = null; goto IL_0314; } if (<>4__this._verbose) { Plugin.LogS.LogDebug((object)(<nudged>5__1 ? "[VoiceFix] Keep-alive nudge sent." : "[VoiceFix] Keep-alive skipped (no backend).")); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private float _silenceSecondsBeforeReinit; private float _keepAliveEverySeconds; private float _reinitCooldownSeconds; private bool _enableAutoReinit; private bool _enableKeepAlive; private bool _verbose; private KeyCode _forceKey; private float _lastHeardTime; private float _lastKeepAlive; private float _lastReinit; private bool _inited; private Behaviour _dissonanceComms; private Behaviour _vivoxMgr; private Behaviour _genericVoiceMgr; private readonly List<AudioActivityTap> _taps = new List<AudioActivityTap>(); private const float DiscoveryInterval = 12f; private float _lastDiscovery; public void Init(float silence, float keepalive, float cooldown, bool autoReinit, bool keepAlive, bool verbose, KeyCode forceKey) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) _silenceSecondsBeforeReinit = Mathf.Max(5f, silence); _keepAliveEverySeconds = Mathf.Max(5f, keepalive); _reinitCooldownSeconds = Mathf.Max(5f, cooldown); _enableAutoReinit = autoReinit; _enableKeepAlive = keepAlive; _verbose = verbose; _forceKey = forceKey; _lastHeardTime = Time.realtimeSinceStartup; _lastKeepAlive = 0f; _lastReinit = -999f; _lastDiscovery = -999f; ((MonoBehaviour)this).StartCoroutine(LateStart()); } private IEnumerator LateStart() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LateStart>d__18(0) { <>4__this = this }; } private void Update() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!_inited) { return; } if (Input.GetKey((KeyCode)304) && Input.GetKeyDown(_forceKey)) { Plugin.LogS.LogWarning((object)"[VoiceFix] Manual re-init requested."); ((MonoBehaviour)this).StartCoroutine(ReinitializeVoice("manual-hotkey")); } bool flag = false; for (int i = 0; i < _taps.Count; i++) { AudioActivityTap audioActivityTap = _taps[i]; if (!((Object)(object)audioActivityTap == (Object)null) && audioActivityTap.ConsumeActivity()) { flag = true; break; } } if (flag) { HeardActivity(); } if (_enableKeepAlive && Time.realtimeSinceStartup - _lastKeepAlive >= _keepAliveEverySeconds) { _lastKeepAlive = Time.realtimeSinceStartup; ((MonoBehaviour)this).StartCoroutine(SendKeepAlive()); } if (_enableAutoReinit && Time.realtimeSinceStartup - _lastHeardTime >= _silenceSecondsBeforeReinit && Time.realtimeSinceStartup - _lastReinit >= _reinitCooldownSeconds) { Plugin.LogS.LogWarning((object)"[VoiceFix] No inbound voice detected for threshold; attempting re-init."); ((MonoBehaviour)this).StartCoroutine(ReinitializeVoice("silence-watchdog")); } if (Time.realtimeSinceStartup - _lastDiscovery >= 12f) { _lastDiscovery = Time.realtimeSinceStartup; DiscoverBackend(); } } private void DiscoverBackend() { try { _dissonanceComms = null; _vivoxMgr = null; _genericVoiceMgr = null; _dissonanceComms = FindBehaviourByTypeName("DissonanceComms"); if ((Object)(object)_dissonanceComms != (Object)null) { Plugin.LogS.LogInfo((object)"[VoiceFix] Found DissonanceComms."); } _vivoxMgr = FindBehaviourByTypeName("VivoxVoiceManager"); if ((Object)(object)_vivoxMgr != (Object)null) { Plugin.LogS.LogInfo((object)"[VoiceFix] Found VivoxVoiceManager."); } if ((Object)(object)_dissonanceComms == (Object)null && (Object)(object)_vivoxMgr == (Object)null) { Behaviour genericVoiceMgr = ((IEnumerable<Behaviour>)Object.FindObjectsOfType<Behaviour>()).FirstOrDefault((Func<Behaviour, bool>)((Behaviour c) => (Object)(object)c != (Object)null && ((object)c).GetType().Name.IndexOf("Voice", StringComparison.OrdinalIgnoreCase) >= 0 && ((object)c).GetType().Name.IndexOf("Manager", StringComparison.OrdinalIgnoreCase) >= 0)); _genericVoiceMgr = genericVoiceMgr; if ((Object)(object)_genericVoiceMgr != (Object)null) { Plugin.LogS.LogInfo((object)("[VoiceFix] Found generic voice manager: " + ((object)_genericVoiceMgr).GetType().FullName)); } else { Plugin.LogS.LogWarning((object)"[VoiceFix] No obvious voice backend found; watchdog will still monitor audio sources."); } } } catch (Exception arg) { Plugin.LogS.LogError((object)$"[VoiceFix] Discovery error: {arg}"); } } private Behaviour FindBehaviourByTypeName(string typeName) { Behaviour[] array = Object.FindObjectsOfType<Behaviour>(); foreach (Behaviour val in array) { if (!((Object)(object)val == (Object)null)) { Type type = ((object)val).GetType(); if (type.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase) || (type.FullName != null && type.FullName.EndsWith("." + typeName, StringComparison.OrdinalIgnoreCase))) { return val; } } } return null; } private void AttachAudioTaps() { List<GameObject> list = new List<GameObject>(); try { GameObject[] array = GameObject.FindGameObjectsWithTag("Player"); if (array != null && array.Length != 0) { list.AddRange(array); } } catch { } AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>(); foreach (AudioSource val in array2) { if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy) { string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); if (text.Contains("voice") || text.Contains("dissonance") || text.Contains("vivox") || text.Contains("radio") || text.Contains("prox")) { list.Add(((Component)val).gameObject); } else if ((Object)(object)val.clip == (Object)null) { list.Add(((Component)val).gameObject); } } } list = list.Distinct().ToList(); int num = 0; foreach (GameObject item in list) { if (!((Object)(object)item == (Object)null)) { AudioActivityTap audioActivityTap = item.GetComponent<AudioActivityTap>(); if ((Object)(object)audioActivityTap == (Object)null) { audioActivityTap = item.AddComponent<AudioActivityTap>(); } if (!_taps.Contains(audioActivityTap)) { _taps.Add(audioActivityTap); } num++; } } Plugin.LogS.LogInfo((object)$"[VoiceFix] Attached audio activity taps to {num} object(s)."); } private void HeardActivity() { _lastHeardTime = Time.realtimeSinceStartup; if (_verbose) { Plugin.LogS.LogDebug((object)$"[VoiceFix] Heard inbound audio @ {_lastHeardTime:F1}s"); } } private IEnumerator SendKeepAlive() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SendKeepAlive>d__24(0) { <>4__this = this }; } private IEnumerator ReinitializeVoice(string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ReinitializeVoice>d__25(0) { <>4__this = this, reason = reason }; } private PropertyInfo FindFirstProperty(Type t, string[] candidates) { foreach (string name in candidates) { PropertyInfo property = t.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property != null) { return property; } } return null; } private bool SafeConvertToBool(object o, bool fallback) { if (o == null) { return fallback; } try { return Convert.ToBoolean(o); } catch { return fallback; } } } internal class AudioActivityTap : MonoBehaviour { private const float Threshold = 0.0005f; private volatile int _activityFlag = 0; private void OnAudioFilterRead(float[] data, int channels) { if (data != null && data.Length != 0) { int num = Math.Max(1, channels); double num2 = 0.0; for (int i = 0; i < data.Length; i += num) { num2 += (double)Math.Abs(data[i]); } double num3 = Math.Max(1, data.Length / num); double num4 = num2 / num3; if (num4 > 0.0005000000237487257) { Interlocked.Exchange(ref _activityFlag, 1); } } } public bool ConsumeActivity() { int num = Interlocked.Exchange(ref _activityFlag, 0); return num != 0; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "VoiceFixMod"; public const string PLUGIN_NAME = "My first plugin"; public const string PLUGIN_VERSION = "1.0.0"; } }