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 MaskWhisper v2.0.0
MaskWhisper.dll
Decompiled 2 years ago#define DEBUG using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using MaskWhisper.WhisperLogic; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Networking; [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: AssemblyCompany("TestAccount666.MaskWhisper")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0")] [assembly: AssemblyProduct("MaskWhisper")] [assembly: AssemblyTitle("TestAccount666.MaskWhisper")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 MaskWhisper { [BepInPlugin("TestAccount666.MaskWhisper", "MaskWhisper", "2.0.0")] public class MaskWhisper : BaseUnityPlugin { internal static List<AudioClip> whisperAudioClips; public static MaskWhisper Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Patch(); string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (directoryName == null) { Logger.LogError((object)"An error occured while trying to find the assembly directory. Please report this!"); return; } whisperAudioClips = new List<AudioClip>(); string text = Path.Combine(directoryName, "whispers"); text = (Directory.Exists(text) ? text : Path.Combine(directoryName)); for (int i = 1; i <= 3; i++) { ((MonoBehaviour)this).StartCoroutine(LoadAudioClipFromFile(new Uri(Path.Combine(text, $"whisper{i}.wav")), $"whisper{i}")); } Logger.LogInfo((object)"TestAccount666.MaskWhisper v2.0.0 has loaded!"); } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("TestAccount666.MaskWhisper"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } private static IEnumerator LoadAudioClipFromFile(Uri filePath, string name) { UnityWebRequest unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(filePath, (AudioType)20); try { yield return unityWebRequest.SendWebRequest(); if ((int)unityWebRequest.result != 1) { Logger.LogError((object)("Failed to load AudioClip: " + unityWebRequest.error)); yield break; } AudioClip clip = DownloadHandlerAudioClip.GetContent(unityWebRequest); whisperAudioClips.Add(clip); ((Object)clip).name = name; Logger.LogInfo((object)("Loaded clip '" + name + "'!")); } finally { ((IDisposable)unityWebRequest)?.Dispose(); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "TestAccount666.MaskWhisper"; public const string PLUGIN_NAME = "MaskWhisper"; public const string PLUGIN_VERSION = "2.0.0"; } } namespace MaskWhisper.WhisperLogic { public class PocketWhisper : WhisperBase { private Coroutine? _waitUntilResetRoutine; private WhisperChecker? _whisperChecker; internal void SetWhisperChecker(WhisperChecker whisperChecker) { _whisperChecker = whisperChecker; } protected override void Start() { base.Start(); ((MonoBehaviour)this).StartCoroutine(TickPocketWhisper()); } private void Update() { HandleDrop(); HandleVolume(); } private void HandleDrop() { if (!((Object)(object)hauntedMaskItem == (Object)null) && !((Object)(object)audioSource == (Object)null) && !((GrabbableObject)hauntedMaskItem).isHeld) { DestroyEarly(); } } private void HandleVolume() { if ((Object)(object)hauntedMaskItem == (Object)null || (Object)(object)audioSource == (Object)null || !((GrabbableObject)hauntedMaskItem).isHeld) { return; } PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null || (Object)(object)((GrabbableObject)hauntedMaskItem).playerHeldBy != (Object)(object)localPlayerController) { return; } if (((GrabbableObject)hauntedMaskItem).isPocketed) { if ((Object)(object)audioSource != (Object)null) { audioSource.volume = 0.5f; } } else if ((Object)(object)audioSource != (Object)null) { audioSource.volume = 1f; } } private IEnumerator TickPocketWhisper() { while (true) { if ((Object)(object)_whisperChecker != (Object)null && (Object)(object)_whisperChecker.audioSource != (Object)null && _whisperChecker.audioSource.isPlaying) { yield return (object)new WaitForEndOfFrame(); continue; } if ((Object)(object)audioSource != (Object)null && audioSource.isPlaying) { yield return (object)new WaitForEndOfFrame(); continue; } if ((Object)(object)hauntedMaskItem == (Object)null) { yield return (object)new WaitForEndOfFrame(); continue; } Debug.Assert((Object)(object)hauntedMaskItem != (Object)null, "hauntedMaskItem != null"); if (!((GrabbableObject)hauntedMaskItem).isHeld) { yield return (object)new WaitForEndOfFrame(); continue; } PlayerControllerB player = StartOfRound.Instance.localPlayerController; if ((Object)(object)player == (Object)null) { yield return (object)new WaitForEndOfFrame(); continue; } if ((Object)(object)((GrabbableObject)hauntedMaskItem).playerHeldBy != (Object)(object)player) { yield return (object)new WaitForEndOfFrame(); continue; } int whisperChance = WhisperBase.Random.Next(0, 100); if (whisperChance < 55) { yield return (object)new WaitForSeconds(25f); continue; } StartWhisper(); yield return (object)new WaitForSeconds(25f); } } private new void StartWhisper() { if (_waitUntilResetRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_waitUntilResetRoutine); } _waitUntilResetRoutine = null; float seconds = base.StartWhisper(); _waitUntilResetRoutine = ((MonoBehaviour)this).StartCoroutine(WaitForSecondsBeforeReset(seconds)); } private static IEnumerator WaitForSecondsBeforeReset(float seconds) { yield return (object)new WaitForSeconds(seconds); SoundManager.Instance.SetDiageticMixerSnapshot(0, 2f); } internal override void DestroyEarly() { if (_waitUntilResetRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_waitUntilResetRoutine); } _waitUntilResetRoutine = null; base.DestroyEarly(); } } public abstract class WhisperBase : MonoBehaviour { protected HauntedMaskItem? hauntedMaskItem; protected static readonly Random Random = new Random(); protected int? instanceId; protected internal AudioSource? audioSource; protected virtual void Start() { hauntedMaskItem = ((Component)this).GetComponent<HauntedMaskItem>(); } internal virtual void DestroyEarly() { Debug.Assert(instanceId.HasValue, "instanceId != null"); Object.Destroy(Object.FindObjectFromInstanceID(instanceId.Value)); SoundManager.Instance.SetDiageticMixerSnapshot(0, 0f); } protected float StartWhisper() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown SoundManager.Instance.SetDiageticMixerSnapshot(1, 8f); GameObject val = new GameObject("TemporaryWhisperAudio"); instanceId = ((Object)val).GetInstanceID(); int count = MaskWhisper.whisperAudioClips.Count; AudioClip val2 = MaskWhisper.whisperAudioClips[Random.Next(0, count)]; audioSource = val.AddComponent<AudioSource>(); audioSource.clip = val2; audioSource.volume = 1f; audioSource.Play(); Object.Destroy((Object)(object)val, val2.length); return val2.length; } } public class WhisperChecker : WhisperBase { private PocketWhisper _pocketWhisper = null; protected override void Start() { base.Start(); _pocketWhisper = ((Component)this).GetComponent<PocketWhisper>(); _pocketWhisper.SetWhisperChecker(this); } private void Update() { if (instanceId.HasValue && Object.FindObjectFromInstanceID(instanceId.Value) != (Object)null) { CheckForNonLineOfSight(); } else { CheckForLineOfSight(); } } private void CheckForNonLineOfSight() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hauntedMaskItem == (Object)null) { return; } PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { return; } Vector3 position = ((Component)this).transform.position; if (!HasLineOfSight(localPlayerController, position)) { DestroyEarly(); return; } float num = Vector3.Distance(((Component)localPlayerController).transform.position, ((Component)this).transform.position); if (!(num < 10f)) { DestroyEarly(); } } private void CheckForLineOfSight() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hauntedMaskItem == (Object)null || ((Object)(object)_pocketWhisper.audioSource != (Object)null && _pocketWhisper.audioSource.isPlaying)) { return; } PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { return; } Vector3 position = ((Component)this).transform.position; if (HasLineOfSight(localPlayerController, position)) { float num = Vector3.Distance(((Component)localPlayerController).transform.position, ((Component)this).transform.position); if (!(num >= 10f)) { StartWhisper(); } } } private bool HasLineOfSight(PlayerControllerB player, Vector3 objectPosition) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) Debug.Assert((Object)(object)hauntedMaskItem != (Object)null, "hauntedMaskItem != null"); bool isHeld = ((GrabbableObject)hauntedMaskItem).isHeld; bool flag = !((GrabbableObject)hauntedMaskItem).isPocketed; bool flag2 = isHeld && (Object)(object)((GrabbableObject)hauntedMaskItem).playerHeldBy == (Object)(object)player; return (flag2 && flag) || (flag && player.HasLineOfSightToPosition(objectPosition, 45f, 60, -1f)); } } } namespace MaskWhisper.Patches { [HarmonyPatch(typeof(GrabbableObject))] public class GrabbableObjectPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(GrabbableObject __instance) { if (((object)__instance).GetType().IsSubclassOf(typeof(HauntedMaskItem)) || !(((object)__instance).GetType() != typeof(HauntedMaskItem))) { GameObject gameObject = ((Component)__instance).gameObject; gameObject.AddComponent<PocketWhisper>(); gameObject.AddComponent<WhisperChecker>(); } } } }