using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using FMOD.Studio; using FMODUnity; using FistVR; using HarmonyLib; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: AssemblyCompany("AmbientMuter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AmbientMuter")] [assembly: AssemblyTitle("AmbientMuter")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace AmbientMuter; [BepInPlugin("h3vr.invent60.ambientmuter", "AmbientMuter", "1.0.7")] public class AmbientMuterPlugin : BaseUnityPlugin { private ConfigEntry _cfgMuteMusic; private ConfigEntry _cfgMuteAmbient; private ConfigEntry _cfgSweepDelay; private ConfigEntry _cfgKeepFootsteps; private ConfigEntry _cfgKeepInteractive; private ConfigEntry _cfgMutePlayerHurt; private Bus _musicBus; private bool _busObtained; private Harmony _harmony; private bool _calibrated; private int _calibrationAttempts; private void Awake() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown BindConfig(); SceneManager.sceneLoaded += OnSceneLoaded; _harmony = new Harmony("h3vr.invent60.ambientmuter"); _harmony.PatchAll(typeof(CursedLLPitchFix)); try { _harmony.PatchAll(typeof(MagBoopTimerFix)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[AmbientMuter] MagBoop slow-mo timer fix applied."); } catch { } ((MonoBehaviour)this).StartCoroutine(DetectCursedLL()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[AmbientMuter] Loaded."); } private void BindConfig() { _cfgMuteMusic = ((BaseUnityPlugin)this).Config.Bind("Music", "Mute map music", true, "Zeros the FMOD music bus every frame, silencing background music in all maps (TNH, outdoor assault maps, etc.). Overrides any other mod that sets music volume."); _cfgMuteAmbient = ((BaseUnityPlugin)this).Config.Bind("Ambient", "Mute ambient sounds", true, "Mutes map ambient AudioSources (wind loops, propaganda speakers, environment drones). Applied once per scene load after the sweep delay."); _cfgSweepDelay = ((BaseUnityPlugin)this).Config.Bind("Ambient", "Sweep delay seconds", 4f, "Seconds to wait after scene load before sweeping ambient sources. Increase if some ambient sounds are not being caught. (0 to 30)"); _cfgKeepInteractive = ((BaseUnityPlugin)this).Config.Bind("Ambient", "Keep interactive object sounds", true, "Buttons, levers, switches, and other interactive map objects keep their sounds. Disable to also silence these."); _cfgKeepFootsteps = ((BaseUnityPlugin)this).Config.Bind("Player", "Keep footstep mod sounds", true, "Footstep mods (PlayerFootsteps, AlyxFootsteps, EFT Frame, BF4 Footsteps) are not silenced. Disable to mute footstep sounds too."); _cfgMutePlayerHurt = ((BaseUnityPlugin)this).Config.Bind("Player", "Mute player hurt sounds", false, "Mutes pain and impact sounds when the player takes damage."); } private IEnumerator DetectCursedLL() { yield return null; try { PropertyInfo property = typeof(AudioSource).GetProperty("pitch"); if ((object)property == null) { yield break; } MethodInfo setMethod = property.GetSetMethod(); if ((object)setMethod == null) { yield break; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)setMethod); if (patchInfo == null) { yield break; } int num = 0; foreach (Patch prefix in patchInfo.Prefixes) { if (!string.Equals(prefix.owner, "h3vr.invent60.ambientmuter", StringComparison.OrdinalIgnoreCase)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[AmbientMuter] pitch-setter prefix: " + prefix.owner)); num++; } } foreach (Patch postfix in patchInfo.Postfixes) { if (!string.Equals(postfix.owner, "h3vr.invent60.ambientmuter", StringComparison.OrdinalIgnoreCase)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[AmbientMuter] pitch-setter postfix: " + postfix.owner)); num++; } } foreach (Patch transpiler in patchInfo.Transpilers) { if (!string.Equals(transpiler.owner, "h3vr.invent60.ambientmuter", StringComparison.OrdinalIgnoreCase)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[AmbientMuter] pitch-setter transpiler: " + transpiler.owner)); num++; } } if (num > 0) { CursedLLPitchFix.PatcherDetected = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("[AmbientMuter] pitch-setter patcher(s) found (" + num + "). Calibration deferred to first slow-mo.")); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[AmbientMuter] CursedLL pitch fix: not needed"); } } catch { } } private void TryGetBus() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) try { _musicBus = RuntimeManager.GetBus("bus:/Music"); _busObtained = true; } catch { } } private void Update() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) CursedLLPitchFix.CachedTimeScale = Time.timeScale; if (CursedLLPitchFix.PatcherDetected && !_calibrated && _calibrationAttempts < 5 && Time.timeScale < 0.99f && Time.timeScale > 0.001f) { _calibrationAttempts++; MeasurePitchCompound(); _calibrated = CursedLLPitchFix.Initialized; } if (!_cfgMuteMusic.Value) { return; } if (!_busObtained) { TryGetBus(); return; } try { ((Bus)(ref _musicBus)).setVolume(0f); } catch { _busObtained = false; } } private void MeasurePitchCompound() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown try { float cachedTimeScale = CursedLLPitchFix.CachedTimeScale; if (cachedTimeScale <= 0.001f || cachedTimeScale >= 0.999f) { return; } GameObject val = new GameObject("__AMCalib"); AudioSource obj = val.AddComponent(); obj.volume = 0f; obj.mute = true; obj.pitch = 1f; float pitch = obj.pitch; Object.Destroy((Object)(object)val); if (pitch <= 0f) { return; } float num = Mathf.Log(cachedTimeScale); float num2 = Mathf.Log(pitch); if (!(Mathf.Abs(num) < 0.0001f)) { int num3 = Mathf.RoundToInt(num2 / num); if (num3 > 0) { CursedLLPitchFix.CompoundLevels = num3; CursedLLPitchFix.ExtraCompounders = Mathf.Max(0, num3 - 1); CursedLLPitchFix.CursedActive = true; CursedLLPitchFix.Initialized = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[AmbientMuter] CursedLL calibrated: {num3} compound level(s), {CursedLLPitchFix.ExtraCompounders} extra (ts={cachedTimeScale:F3})"); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[AmbientMuter] CursedLL calibration error: " + ex.Message)); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { _busObtained = false; if (_cfgMuteAmbient.Value) { ((MonoBehaviour)this).StartCoroutine(MuteAmbientDelayed()); } } private IEnumerator MuteAmbientDelayed() { yield return (object)new WaitForSeconds(_cfgSweepDelay.Value); MuteAmbientSources(); } private void MuteAmbientSources() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) bool value = _cfgKeepFootsteps.Value; bool value2 = _cfgKeepInteractive.Value; bool value3 = _cfgMutePlayerHurt.Value; int num = 0; int num2 = 0; AudioSource[] array = Object.FindObjectsOfType(); foreach (AudioSource val in array) { if ((Object)(object)((Component)val).GetComponent() != (Object)null) { num2++; continue; } if (value) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).name == "DontDestroyOnLoad") { num2++; continue; } } if (value2 && (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { num2++; continue; } if (!value2 && (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { num2++; continue; } if ((Object)(object)((Component)val).GetComponentInParent() != (Object)null) { num2++; continue; } if ((Object)(object)((Component)val).GetComponentInParent() != (Object)null && !value3) { num2++; continue; } if (value && (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { num2++; continue; } val.mute = true; num++; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[AmbientMuter] Scene sweep done. Muted: {num}, Kept: {num2}"); } } [HarmonyPatch] public static class MagBoopTimerFix { private static MethodBase TargetMethod() { return AccessTools.Method("MagBoop.MagTriggerScript:Update", (Type[])null, (Type[])null); } [HarmonyTranspiler] private static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo getMethod = typeof(Time).GetProperty("fixedUnscaledDeltaTime").GetGetMethod(); List list = instructions.ToList(); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Call && list[i].operand is MethodInfo methodInfo && methodInfo.DeclaringType == typeof(Time) && methodInfo.Name == "get_fixedDeltaTime") { list[i].operand = getMethod; } } return list; } } public static class CursedLLPitchFix { public static bool PatcherDetected = false; public static bool Initialized = false; public static bool CursedActive = false; public static int CompoundLevels = 0; public static int ExtraCompounders = 0; public static float CachedTimeScale = 1f; [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] public static void CompensatePitchRead(ref float __result) { if (Initialized && CursedActive && !(CachedTimeScale >= 0.9999f) && !(CachedTimeScale <= 0.001f)) { __result /= CachedTimeScale; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] public static void PreCompensatePitchSet(ref float value) { if (Initialized && CursedActive && !(CachedTimeScale >= 0.9999f) && !(CachedTimeScale <= 0.001f) && ExtraCompounders > 0) { for (int i = 0; i < ExtraCompounders; i++) { value /= CachedTimeScale; } } } }