Decompiled source of Spookbox v1.0.1

Spookbox.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using ContentWarningShop;
using ContentWarningShop.Localisation;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Spookbox.Behaviour;
using Spookbox.Entries;
using Spookbox.Settings;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using Zorro.Core.Serizalization;
using Zorro.Settings;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("0Harmony")]
[assembly: IgnoresAccessChecksTo("Ashley.MeshSplitter")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")]
[assembly: IgnoresAccessChecksTo("Discord")]
[assembly: IgnoresAccessChecksTo("HBAO.Demo.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("HBAO.Runtime")]
[assembly: IgnoresAccessChecksTo("HBAO.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("LocalizationAssembly")]
[assembly: IgnoresAccessChecksTo("MeshSplit")]
[assembly: IgnoresAccessChecksTo("ModalAssembly")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Mdb")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Pdb")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Rocks")]
[assembly: IgnoresAccessChecksTo("Mono.Security")]
[assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")]
[assembly: IgnoresAccessChecksTo("MonoMod.Utils")]
[assembly: IgnoresAccessChecksTo("mscorlib")]
[assembly: IgnoresAccessChecksTo("netstandard")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("pworld")]
[assembly: IgnoresAccessChecksTo("sc.posteffects.runtime")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("SteamManagerAssembly")]
[assembly: IgnoresAccessChecksTo("System.ComponentModel.Composition")]
[assembly: IgnoresAccessChecksTo("System.Configuration")]
[assembly: IgnoresAccessChecksTo("System.Core")]
[assembly: IgnoresAccessChecksTo("System.Data.DataSetExtensions")]
[assembly: IgnoresAccessChecksTo("System.Data")]
[assembly: IgnoresAccessChecksTo("System")]
[assembly: IgnoresAccessChecksTo("System.Drawing")]
[assembly: IgnoresAccessChecksTo("System.EnterpriseServices")]
[assembly: IgnoresAccessChecksTo("System.IO.Compression")]
[assembly: IgnoresAccessChecksTo("System.IO.Compression.FileSystem")]
[assembly: IgnoresAccessChecksTo("System.Net.Http")]
[assembly: IgnoresAccessChecksTo("System.Numerics")]
[assembly: IgnoresAccessChecksTo("System.Runtime")]
[assembly: IgnoresAccessChecksTo("System.Runtime.Serialization")]
[assembly: IgnoresAccessChecksTo("System.Security")]
[assembly: IgnoresAccessChecksTo("System.ServiceModel.Internals")]
[assembly: IgnoresAccessChecksTo("System.Transactions")]
[assembly: IgnoresAccessChecksTo("System.Xml")]
[assembly: IgnoresAccessChecksTo("System.Xml.Linq")]
[assembly: IgnoresAccessChecksTo("Tayx.Graphy")]
[assembly: IgnoresAccessChecksTo("Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.003")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")]
[assembly: IgnoresAccessChecksTo("Unity.Localization")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.PlayableGraphVisualizer")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Shaders")]
[assembly: IgnoresAccessChecksTo("Unity.ResourceManager")]
[assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")]
[assembly: IgnoresAccessChecksTo("Unity.Splines")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VectorGraphics")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AccessibilityModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AndroidJNIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AnimationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClothModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterInputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterRendererModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ContentLoadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CrashReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DirectorModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DSPGraphModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GameCenterModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ProfilerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SharedInternalsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteMaskModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteShapeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.StreamingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubstanceModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubsystemsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainPhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreFontEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreTextEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextRenderingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TilemapModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TLSModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIElementsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UmbraModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsCommonModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityConnectModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityCurlModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityTestProtocolModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestTextureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestWWWModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VehiclesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VFXModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VideoModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VirtualTexturingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VRModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.WindModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XRModule")]
[assembly: IgnoresAccessChecksTo("VerboseAssembly")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.AutoLOD")]
[assembly: IgnoresAccessChecksTo("Zorro.ControllerSupport")]
[assembly: IgnoresAccessChecksTo("Zorro.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.Localization")]
[assembly: IgnoresAccessChecksTo("Zorro.PhotonUtility")]
[assembly: IgnoresAccessChecksTo("Zorro.Recorder")]
[assembly: IgnoresAccessChecksTo("Zorro.Settings.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.UI.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Spookbox")]
[assembly: AssemblyConfiguration("Modman (Release)")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2ec0eebb798da4c64211bed7adbc23b466ddfe28")]
[assembly: AssemblyProduct("Spookbox")]
[assembly: AssemblyTitle("Spookbox")]
[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.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 Spookbox
{
	[HarmonyPatch(typeof(GameHandler))]
	internal class GameHandlerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Initialize")]
		private static void Initialize()
		{
			SpookboxPlugin.InitialiseSettings();
		}
	}
	public static class Mixtape
	{
		public const string ASYNC_LOAD_ENV = "-ihaveanssd";

		public const string TRACKS_DIR_NAME = "SpookboxMixtape";

		private static bool _asyncLoadTracks = false;

		public const int MAX_TRACKS = 255;

		public static readonly List<AudioClip> Tracks = new List<AudioClip>();

		public static int Length => Tracks.Count;

		public static bool HasTracks()
		{
			return Tracks.Count > 0;
		}

		public static void LoadTracks()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Invalid comparison between Unknown and I4
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			_asyncLoadTracks = Environment.GetCommandLineArgs().Contains("-ihaveanssd");
			Debug.Log((object)string.Format("Async load audio clips ({0} flag) : {1}", "-ihaveanssd", _asyncLoadTracks));
			Tracks.Clear();
			List<string> allTracks = GetAllTracks();
			Debug.Log((object)$"{allTracks.Count} potential mixtape tracks found.");
			foreach (string item in allTracks)
			{
				if (Tracks.Count == 255)
				{
					Debug.LogWarning((object)$"Mixtape full: maximum track count limit reached ({255}).");
					break;
				}
				AudioType audioType = GetAudioType(item);
				if ((int)audioType == 0)
				{
					Debug.LogWarning((object)("Track \"" + item + "\" could not be loaded due to unsupported audio type."));
					continue;
				}
				AudioClip val = LoadAudioClipFromFile(item, GetAudioType(item));
				if (!((Object)(object)val == (Object)null))
				{
					((Object)val).name = Path.GetFileNameWithoutExtension(item);
					Tracks.Add(val);
					Debug.Log((object)("Added track to mixtape: " + ((Object)val).name));
				}
			}
		}

		private static string GetUserMusicDirPath()
		{
			return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic), "SpookboxMixtape");
		}

		private static string GetPluginMusicDirPath()
		{
			string fullPath = Path.GetFullPath(Path.Combine(SpookboxPlugin.PluginDirPath, "SpookboxMixtape"));
			if (!Directory.Exists(fullPath))
			{
				Directory.CreateDirectory(fullPath);
			}
			return fullPath;
		}

		internal static List<string> GetAllTracks()
		{
			List<string> list = new List<string>();
			list.AddRange(GetTracksFromDir(GetUserMusicDirPath()));
			list.AddRange(GetTracksFromDir(GetPluginMusicDirPath()));
			string path = Path.Combine(SpookboxPlugin.PluginDirPath, "..\\");
			string[] directories = Directory.GetDirectories(path);
			string[] array = directories;
			foreach (string path2 in array)
			{
				list.AddRange(GetTracksFromDir(Path.Combine(path2, "SpookboxMixtape")));
			}
			return list.OrderBy<string, string>(Path.GetFileName, StringComparer.InvariantCultureIgnoreCase).ToList();
		}

		private static IEnumerable<string> GetTracksFromDir(string path)
		{
			IEnumerable<string> result = Array.Empty<string>();
			if (!Directory.Exists(path))
			{
				return result;
			}
			return from p in Directory.GetFiles(path)
				where (int)GetAudioType(p) != 0 && !p.Contains('\ufffd')
				select p;
		}

		private static AudioType GetAudioType(string path)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			return (AudioType)(Path.GetExtension(path).ToLower() switch
			{
				".wav" => 20, 
				".ogg" => 14, 
				".mp3" => 13, 
				_ => 0, 
			});
		}

		private static AudioClip LoadAudioClipFromFile(string path, AudioType type)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			AudioClip result = null;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, type);
			if (_asyncLoadTracks)
			{
				((DownloadHandlerAudioClip)audioClip.downloadHandler).streamAudio = true;
			}
			try
			{
				audioClip.SendWebRequest();
				try
				{
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result == 1)
					{
						result = DownloadHandlerAudioClip.GetContent(audioClip);
					}
					else
					{
						Debug.LogError((object)("Loading AudioClip from " + path + " failed: " + audioClip.error));
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)"Loading AudioClip failed:");
					Debug.LogException(ex);
				}
			}
			catch (Exception ex2)
			{
				Debug.LogError((object)("Request for " + path + " failed:"));
				Debug.LogException(ex2);
			}
			finally
			{
				if (audioClip != null)
				{
					audioClip.Dispose();
				}
			}
			return result;
		}
	}
	[ContentWarningPlugin("xerren.cwspookbox", "1.0.0", false)]
	[BepInPlugin("xerren.cwspookbox", "Spöökbox", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SpookboxPlugin : BaseUnityPlugin
	{
		private static bool _initialised = false;

		private const string ALERT_META_GUID = "bigslapTunes";

		internal static readonly SynchronisedMetadata<bool> AlertMonsters = new SynchronisedMetadata<bool>("xerren.cwspookbox_bigslapTunes", true);

		private static BoomboxAlertSetting _alertSetting;

		private const string INF_BATTERY_META_GUID = "infiniteBattery";

		internal static readonly SynchronisedMetadata<bool> InfiniteBattery = new SynchronisedMetadata<bool>("xerren.cwspookbox_infiniteBattery", false);

		private static BoomboxInfiniteBatterySetting _infiniteBatterySetting;

		private static BoomboxPriceSetting _priceSetting;

		public const string MOD_GUID = "xerren.cwspookbox";

		public const string MOD_NAME = "Spöökbox";

		public const string MOD_VER = "1.0.0";

		internal static Item _spookboxItem;

		internal const string SPOOKBOX_GUID = "91f31218-6507-4bef-928d-e76b33f44a51";

		internal static AssetBundle _bundle;

		private static Harmony harmony = new Harmony("xerren.cwspookbox");

		public static string PluginDirPath => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		internal static void InitialiseSettings()
		{
			if (!_initialised)
			{
				_alertSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxAlertSetting>();
				_alertSetting.Changed += _alertSetting_Changed;
				AlertMonsters.SetValue(((BoolSetting)_alertSetting).Value);
				_infiniteBatterySetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxInfiniteBatterySetting>();
				_infiniteBatterySetting.Changed += _infiniteBatterySetting_Changed;
				InfiniteBattery.SetValue(((BoolSetting)_infiniteBatterySetting).Value);
				_priceSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxPriceSetting>();
				_priceSetting.Changed += _priceSetting_Changed;
				_spookboxItem.price = ((IntSetting)_priceSetting).Value;
				_initialised = true;
				Debug.Log((object)"xerren.cwspookbox settings initialised.");
			}
		}

		private static void _priceSetting_Changed(int obj)
		{
			if (!SynchronisedMetadata<bool>.InLobby)
			{
				_spookboxItem.price = obj;
			}
			else
			{
				Debug.LogWarning((object)"Attempted to apply BoomboxPriceSetting value to item while in a lobby. Item price can only be changed outside of the lobby; please restart the lobby to change this setting.");
			}
		}

		private static void _alertSetting_Changed(bool obj)
		{
			if (AlertMonsters.CanSet())
			{
				AlertMonsters.SetValue(obj);
			}
		}

		private static void _infiniteBatterySetting_Changed(bool obj)
		{
			if (InfiniteBattery.CanSet())
			{
				InfiniteBattery.SetValue(obj);
			}
		}

		private void Awake()
		{
			Debug.Log((object)"xerren.cwspookbox initialising via BepInEx mod loader.");
			harmony.PatchAll();
			_bundle = LoadAssetBundle();
			_spookboxItem = _bundle.LoadAsset<Item>("Spookbox");
			_spookboxItem.itemObject.AddComponent<SpookboxBehaviour>();
			Shop.RegisterItem(_spookboxItem);
			Shop.RegisterCustomDataEntries();
			ShopLocalisation.SetDefaultTooltips(_spookboxItem, "{key_use} Play;{key_use2} Next Track");
			Mixtape.LoadTracks();
			Debug.Log((object)"xerren.cwspookbox initialised.");
		}

		private static AssetBundle LoadAssetBundle()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Join(string.op_Implicit(PluginDirPath), string.op_Implicit("spookbox"));
			return AssetBundle.LoadFromFile(text);
		}
	}
}
namespace Spookbox.Settings
{
	[ContentWarningSetting]
	public class BoomboxLocalVolumeSetting : FloatSetting, IExposedSetting
	{
		public event Action<float> Changed;

		public override void ApplyValue()
		{
			this.Changed?.Invoke(((FloatSetting)this).Value);
		}

		public override float GetDefaultValue()
		{
			return 1f;
		}

		public override float2 GetMinMaxValue()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return new float2(0f, 1f);
		}

		public SettingCategory GetSettingCategory()
		{
			return (SettingCategory)4;
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Local volume";
		}

		private void AdjustDetachedSpeakers()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			PlayerInventory val2 = default(PlayerInventory);
			VolumeEntry volumeEntry = default(VolumeEntry);
			foreach (Player player in PlayerHandler.instance.players)
			{
				foreach (Transform cameraPo in player.refs.cameraPos)
				{
					Transform val = cameraPo;
					if (((Object)((Component)val).gameObject).name.Contains("__spookbox_speaker_"))
					{
						string guid = ((Object)((Component)val).gameObject).name.Replace("__spookbox_speaker_", "");
						player.TryGetInventory(ref val2);
						ItemDescriptor val3 = val2.GetItems().Find((ItemDescriptor i) => i.data.m_guid.ToString() == guid);
						val3.data.TryGetEntry<VolumeEntry>(ref volumeEntry);
						((Component)val).gameObject.GetComponent<AudioSource>().volume = volumeEntry.Volume * ((FloatSetting)this).Value;
					}
				}
			}
		}
	}
	[ContentWarningSetting]
	public class BoomboxVolumeUpBindSetting : KeyCodeSetting, IExposedSetting
	{
		public SettingCategory GetSettingCategory()
		{
			return (SettingCategory)4;
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Volume Up Key";
		}

		public override KeyCode GetDefaultKey()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return (KeyCode)280;
		}
	}
	[ContentWarningSetting]
	public class BoomboxVolumeDownBindSetting : KeyCodeSetting, IExposedSetting
	{
		public SettingCategory GetSettingCategory()
		{
			return (SettingCategory)4;
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Volume Down Key";
		}

		public override KeyCode GetDefaultKey()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return (KeyCode)281;
		}
	}
	[ContentWarningSetting]
	public class BoomboxAlertSetting : BoolSetting, IExposedSetting
	{
		public event Action<bool> Changed;

		public override void ApplyValue()
		{
			this.Changed?.Invoke(((BoolSetting)this).Value);
		}

		public SettingCategory GetSettingCategory()
		{
			return (SettingCategory)4;
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Let BigSlap hear the tunes (Host)";
		}

		public override bool GetDefaultValue()
		{
			return true;
		}
	}
	[ContentWarningSetting]
	public class BoomboxInfiniteBatterySetting : BoolSetting, IExposedSetting
	{
		public event Action<bool> Changed;

		public override void ApplyValue()
		{
			this.Changed?.Invoke(((BoolSetting)this).Value);
		}

		public SettingCategory GetSettingCategory()
		{
			return (SettingCategory)4;
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Infinite battery (Host)";
		}

		public override bool GetDefaultValue()
		{
			return false;
		}
	}
	[ContentWarningSetting]
	public class BoomboxPriceSetting : IntSetting, IExposedSetting
	{
		public event Action<int> Changed;

		public override void ApplyValue()
		{
			this.Changed?.Invoke(((IntSetting)this).Value);
		}

		public SettingCategory GetSettingCategory()
		{
			return (SettingCategory)4;
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Price (Host)";
		}

		public override int GetDefaultValue()
		{
			return 100;
		}
	}
}
namespace Spookbox.Entries
{
	public class TrackEntry : ItemDataEntry, IHaveUIData
	{
		private int _trackIndex = 0;

		private const string NO_TRACKS = "No Tracks Found :[";

		private const int MAX_TRACK_NAME_LENGTH = 17;

		public int TrackIndex
		{
			get
			{
				return _trackIndex;
			}
			set
			{
				_trackIndex = Math.Clamp(value, 0, Mixtape.Tracks.Count - 1);
				TrackName = FormatTrackName();
			}
		}

		public string TrackName { get; private set; } = "No Tracks Found :[";


		public override void Deserialize(BinaryDeserializer binaryDeserializer)
		{
			TrackIndex = binaryDeserializer.ReadByte();
		}

		public string GetString()
		{
			return TrackName;
		}

		public override void Serialize(BinarySerializer binarySerializer)
		{
			binarySerializer.WriteByte((byte)TrackIndex);
		}

		private string FormatTrackName()
		{
			string empty = string.Empty;
			List<AudioClip> tracks = Mixtape.Tracks;
			if (tracks.Count == 0)
			{
				return "No Tracks Found :[";
			}
			empty = Path.GetFileNameWithoutExtension(((Object)tracks[TrackIndex]).name);
			if (empty.Length > 17)
			{
				empty = empty.Substring(0, 17) + "...";
			}
			return empty;
		}
	}
	public class VolumeEntry : ItemDataEntry, IHaveUIData
	{
		private float _volume = 0f;

		public const float MaxVolume = 1f;

		public const string UIString = "{0}% Volume";

		public float Volume
		{
			get
			{
				return _volume;
			}
			set
			{
				_volume = Mathf.Clamp01(value);
			}
		}

		public override void Deserialize(BinaryDeserializer binaryDeserializer)
		{
			Volume = (float)(int)binaryDeserializer.ReadByte() / 100f;
		}

		public override void Serialize(BinarySerializer binarySerializer)
		{
			binarySerializer.WriteByte((byte)Mathf.RoundToInt(Volume * 100f));
		}

		public string GetString()
		{
			return $"{Mathf.RoundToInt(Volume * 100f)}% Volume";
		}
	}
}
namespace Spookbox.Behaviour
{
	public class SpookboxBehaviour : ItemInstanceBehaviour
	{
		private GameObject _speakerObject;

		private AudioSource _speaker;

		private SFX_PlayOneShot _interactSFX;

		private BatteryEntry _battery;

		private const float MAX_BATTERY_CHARGE = 180f;

		private OnOffEntry _onOffEntry;

		private VolumeEntry _volume;

		private TrackEntry _track;

		private TimeEntry _playbackTime;

		private BoomboxLocalVolumeSetting _localVolumeSetting;

		private BoomboxVolumeUpBindSetting _volumeUpBindSetting;

		private BoomboxVolumeDownBindSetting _volumeDownBindSetting;

		private float _alertCountdown = 0f;

		private float _alertInterval = 0.15f;

		private int _instanceTrackIndex = -1;

		private void Awake()
		{
			_speakerObject = ((Component)((Component)this).transform.Find("SFX/SpookboxSpeaker")).gameObject;
			_speaker = _speakerObject.GetComponent<AudioSource>();
			_interactSFX = ((Component)((Component)this).transform.Find("SFX/Interact")).GetComponent<SFX_PlayOneShot>();
			_speaker.outputAudioMixerGroup = GameHandler.Instance.SettingsHandler.GetSetting<SFXVolumeSetting>().mixerGroup;
			_localVolumeSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxLocalVolumeSetting>();
			_localVolumeSetting.Changed += _localVolumeSetting_Changed;
			_volumeUpBindSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxVolumeUpBindSetting>();
			_volumeDownBindSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxVolumeDownBindSetting>();
		}

		private void Update()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			if (base.isHeldByMe && !Player.localPlayer.HasLockedInput())
			{
				if (Player.localPlayer.input.clickWasPressed)
				{
					_onOffEntry.on = !_onOffEntry.on;
					((ItemDataEntry)_onOffEntry).SetDirty();
					if (_onOffEntry.on && SpookboxPlugin.AlertMonsters.Value)
					{
						_alertCountdown = _alertInterval;
					}
					ClickButtonSFX();
				}
				if (Player.localPlayer.input.aimWasPressed)
				{
					SetTrack((_track.TrackIndex + 1) % Mixtape.Tracks.Count);
				}
				if (GlobalInputHandler.GetKeyUp(((KeyCodeSetting)_volumeUpBindSetting).Keycode()))
				{
					_volume.Volume += 0.1f;
					((ItemDataEntry)_volume).SetDirty();
					AdjustVolume();
					ClickButtonSFX();
				}
				if (GlobalInputHandler.GetKeyUp(((KeyCodeSetting)_volumeDownBindSetting).Keycode()))
				{
					_volume.Volume -= 0.1f;
					((ItemDataEntry)_volume).SetDirty();
					AdjustVolume();
					ClickButtonSFX();
				}
			}
			if (_onOffEntry.on != _speaker.isPlaying)
			{
				if (_onOffEntry.on)
				{
					_speaker.time = _playbackTime.currentTime;
					_speaker.Play();
				}
				else
				{
					_speaker.Stop();
				}
			}
			if (!_onOffEntry.on)
			{
				return;
			}
			if (_battery.m_charge < 0f)
			{
				_onOffEntry.on = false;
				((ItemDataEntry)_onOffEntry).SetDirty();
				ClickButtonSFX();
			}
			if (SpookboxPlugin.AlertMonsters.Value)
			{
				_alertCountdown -= Time.deltaTime;
				if (_alertCountdown < 0f)
				{
					SFX_Player.instance.PlayNoise(((Component)this).transform.position, 35f, 1);
					_alertCountdown = _alertInterval;
				}
			}
			if (_instanceTrackIndex != _track.TrackIndex)
			{
				_instanceTrackIndex = _track.TrackIndex;
				SetTrack(_instanceTrackIndex, local: true);
				if (_onOffEntry.on)
				{
					_speaker.Play();
				}
				else
				{
					_speaker.Stop();
				}
			}
			if (!SpookboxPlugin.InfiniteBattery.Value)
			{
				BatteryEntry battery = _battery;
				battery.m_charge -= Time.deltaTime;
			}
			_playbackTime.currentTime = _speaker.time;
		}

		private void OnDestroy()
		{
			_localVolumeSetting.Changed -= _localVolumeSetting_Changed;
			base.itemInstance.onItemEquipped.RemoveListener((UnityAction<Player>)OnEquip);
			base.itemInstance.onUnequip.RemoveListener((UnityAction<Player>)OnUnequip);
		}

		private void OnEquip(Player player)
		{
			if (TryReattachSpeaker(player))
			{
				Debug.Log((object)$"Spöökbox speaker reattached: {base.itemInstance.instanceData.m_guid}");
			}
		}

		private void OnUnequip(Player player)
		{
			if (IsItemInPlayerInventory(player, base.itemInstance.instanceData.m_guid) && _onOffEntry.on)
			{
				DetachSpeaker(player);
				Debug.Log((object)$"Spöökbox speaker detached: {base.itemInstance.instanceData.m_guid}");
			}
		}

		private static bool IsItemInPlayerInventory(Player player, Guid itemGuid)
		{
			PlayerInventory val = default(PlayerInventory);
			if (player.TryGetInventory(ref val))
			{
				return val.GetItems().FindIndex((ItemDescriptor item) => item.data.m_guid == itemGuid) != -1;
			}
			return false;
		}

		private GameObject GetDetachedSpeaker(Player player)
		{
			string text = $"__spookbox_speaker_{base.itemInstance.m_guid.Value}";
			Transform cameraPos = player.refs.cameraPos;
			Transform val = cameraPos.Find(text);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return ((Component)val).gameObject;
		}

		private void DetachSpeaker(Player player)
		{
			Transform cameraPos = player.refs.cameraPos;
			GameObject val = SpookboxPlugin._bundle.LoadAsset<GameObject>("SpookboxSpeaker");
			GameObject val2 = Object.Instantiate<GameObject>(val);
			StashedSpookboxBehaviour stashedSpookboxBehaviour = val2.AddComponent<StashedSpookboxBehaviour>();
			stashedSpookboxBehaviour.Configure(_onOffEntry, _battery, _volume.Volume);
			((Object)val2).name = $"__spookbox_speaker_{base.itemInstance.m_guid.Value}";
			val2.transform.SetParent(cameraPos, false);
			AudioSource component = val2.GetComponent<AudioSource>();
			((Behaviour)component).enabled = true;
			component.outputAudioMixerGroup = _speaker.outputAudioMixerGroup;
			component.clip = _speaker.clip;
			component.volume = _volume.Volume * ((FloatSetting)_localVolumeSetting).Value;
			component.time = _playbackTime.currentTime;
			component.Play();
		}

		private bool TryReattachSpeaker(Player player)
		{
			GameObject detachedSpeaker = GetDetachedSpeaker(player);
			if ((Object)(object)detachedSpeaker == (Object)null)
			{
				return false;
			}
			AudioSource component = detachedSpeaker.GetComponent<AudioSource>();
			_speaker.clip = component.clip;
			_speaker.time = component.time;
			_playbackTime.currentTime = component.time;
			Object.Destroy((Object)(object)detachedSpeaker);
			return true;
		}

		private void _localVolumeSetting_Changed(float obj)
		{
			if (!((Object)(object)_speaker == (Object)null))
			{
				AdjustVolume();
			}
		}

		public override void ConfigItem(ItemInstanceData data, PhotonView playerView)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0059: 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_006a: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			if (!data.TryGetEntry<BatteryEntry>(ref _battery))
			{
				_battery = new BatteryEntry
				{
					m_maxCharge = 180f,
					m_charge = 180f
				};
				data.AddDataEntry((ItemDataEntry)(object)_battery);
			}
			if (!data.TryGetEntry<OnOffEntry>(ref _onOffEntry))
			{
				_onOffEntry = new OnOffEntry
				{
					on = false
				};
				data.AddDataEntry((ItemDataEntry)(object)_onOffEntry);
			}
			if (!data.TryGetEntry<VolumeEntry>(ref _volume))
			{
				_volume = new VolumeEntry
				{
					Volume = 0.5f
				};
				data.AddDataEntry((ItemDataEntry)(object)_volume);
			}
			AdjustVolume();
			if (!data.TryGetEntry<TrackEntry>(ref _track))
			{
				_track = new TrackEntry();
				data.AddDataEntry((ItemDataEntry)(object)_track);
			}
			if (!data.TryGetEntry<TimeEntry>(ref _playbackTime))
			{
				_playbackTime = new TimeEntry
				{
					currentTime = 0f
				};
				data.AddDataEntry((ItemDataEntry)(object)_playbackTime);
			}
			base.itemInstance.onItemEquipped.AddListener((UnityAction<Player>)OnEquip);
			base.itemInstance.onUnequip.AddListener((UnityAction<Player>)OnUnequip);
		}

		private void SetTrack(int idx, bool local = false)
		{
			if (Mixtape.HasTracks())
			{
				if (!local)
				{
					_playbackTime.currentTime = 0f;
					((ItemDataEntry)_playbackTime).SetDirty();
					_track.TrackIndex = idx;
					((ItemDataEntry)_track).SetDirty();
					ClickButtonSFX();
				}
				_speaker.clip = Mixtape.Tracks[_track.TrackIndex];
				_speaker.time = _playbackTime.currentTime;
			}
		}

		private void ClickButtonSFX()
		{
			if ((Object)(object)_interactSFX != (Object)null)
			{
				_interactSFX.Play();
			}
		}

		private void AdjustVolume()
		{
			float volume = _volume.Volume * ((FloatSetting)_localVolumeSetting).Value;
			_speaker.volume = volume;
		}
	}
	public class StashedSpookboxBehaviour : MonoBehaviour
	{
		private OnOffEntry _onOffEntry;

		private BatteryEntry _batteryEntry;

		private float _volume;

		private AudioSource _speaker;

		private BoomboxLocalVolumeSetting _localVolumeSetting;

		private void Awake()
		{
			_speaker = ((Component)this).GetComponent<AudioSource>();
			_speaker.outputAudioMixerGroup = GameHandler.Instance.SettingsHandler.GetSetting<SFXVolumeSetting>().mixerGroup;
			_localVolumeSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxLocalVolumeSetting>();
			_localVolumeSetting.Changed += _localVolumeSetting_Changed;
		}

		public void Configure(OnOffEntry onOff, BatteryEntry battery, float volume)
		{
			_onOffEntry = onOff;
			_batteryEntry = battery;
			_volume = volume;
		}

		private void _localVolumeSetting_Changed(float obj)
		{
			_speaker.volume = _volume * obj;
		}

		private void OnDestroy()
		{
			_localVolumeSetting.Changed -= _localVolumeSetting_Changed;
		}

		private void Update()
		{
			if (!SpookboxPlugin.InfiniteBattery.Value)
			{
				if (_batteryEntry.m_charge < 0f)
				{
					_onOffEntry.on = false;
					((ItemDataEntry)_onOffEntry).SetDirty();
					Debug.Log((object)("Stashed " + ((Object)((Component)this).gameObject).name + " destroyed; ran out of battery."));
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				BatteryEntry batteryEntry = _batteryEntry;
				batteryEntry.m_charge -= Time.deltaTime;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}