#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>();
}
}
}
}