Decompiled source of MaskWhisper v2.0.0

MaskWhisper.dll

Decompiled 8 months 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>();
			}
		}
	}
}