Decompiled source of Spookbox v1.3.0

Spookbox.dll

Decompiled 3 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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 Steamworks;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine.UIElements;
using Zorro.Core;
using Zorro.Core.Serizalization;
using Zorro.Settings;
using Zorro.Settings.DebugUI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyFileVersion("1.3.3.44750")]
[assembly: AssemblyInformationalVersion("1.3.3+aece46e683.bepinex")]
[assembly: IgnoresAccessChecksTo("0Harmony")]
[assembly: IgnoresAccessChecksTo("Accessibility")]
[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("Managers")]
[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.Posix")]
[assembly: IgnoresAccessChecksTo("Mono.Security")]
[assembly: IgnoresAccessChecksTo("Mono.WebBrowser")]
[assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")]
[assembly: IgnoresAccessChecksTo("MonoMod.Utils")]
[assembly: IgnoresAccessChecksTo("mscorlib")]
[assembly: IgnoresAccessChecksTo("netstandard")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Photon")]
[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("Platforms")]
[assembly: IgnoresAccessChecksTo("PlayEveryWare.VideoEncoding")]
[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("SteamCommon")]
[assembly: IgnoresAccessChecksTo("SteamManagerAssembly")]
[assembly: IgnoresAccessChecksTo("System.ComponentModel.Composition")]
[assembly: IgnoresAccessChecksTo("System.Configuration")]
[assembly: IgnoresAccessChecksTo("System.Configuration.Install")]
[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.IO.Hashing")]
[assembly: IgnoresAccessChecksTo("System.Memory")]
[assembly: IgnoresAccessChecksTo("System.Net.Http")]
[assembly: IgnoresAccessChecksTo("System.Numerics")]
[assembly: IgnoresAccessChecksTo("System.Runtime.CompilerServices.Unsafe")]
[assembly: IgnoresAccessChecksTo("System.Runtime")]
[assembly: IgnoresAccessChecksTo("System.Runtime.Serialization")]
[assembly: IgnoresAccessChecksTo("System.Runtime.Serialization.Formatters.Soap")]
[assembly: IgnoresAccessChecksTo("System.Security")]
[assembly: IgnoresAccessChecksTo("System.ServiceModel.Internals")]
[assembly: IgnoresAccessChecksTo("System.ServiceProcess")]
[assembly: IgnoresAccessChecksTo("System.Transactions")]
[assembly: IgnoresAccessChecksTo("System.Windows.Forms")]
[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.Microsoft.GDK")]
[assembly: IgnoresAccessChecksTo("Unity.Microsoft.GDK.Tools")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Center.Common")]
[assembly: IgnoresAccessChecksTo("Unity.PlayableGraphVisualizer")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Rendering.LightTransport.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime.Shared")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.GPUDriven.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.2D.Runtime")]
[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.AMDModule")]
[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.GraphicsStateCollectionSerializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HierarchyCoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputForUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.MarshallingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.MultiplayerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ShaderVariantAnalyticsModule")]
[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("Utilities")]
[assembly: IgnoresAccessChecksTo("VerboseAssembly")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")]
[assembly: IgnoresAccessChecksTo("XblPCSandbox")]
[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")]
[assembly: AssemblyProduct("Spookbox")]
[assembly: AssemblyTitle("Spookbox")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.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;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.7.115.8147")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Modman";

	internal const string AssemblyFileVersion = "1.3.3.44750";

	internal const string AssemblyInformationalVersion = "1.3.3+aece46e683.bepinex";

	internal const string AssemblyName = "Spookbox";

	internal const string AssemblyTitle = "Spookbox";

	internal const string AssemblyVersion = "1.3.0.0";

	internal static readonly DateTime GitCommitAuthorDate = new DateTime(638993676340000000L, DateTimeKind.Utc);

	internal static readonly DateTime GitCommitDate = new DateTime(638993676340000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "aece46e6832fc0509d74c0427e9ccbad75735b9d";

	internal const bool IsBepinexBuild = true;

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string RootNamespace = "Spookbox";
}
namespace Spookbox
{
	internal class Logger
	{
		public static void Log(string info)
		{
			Debug.Log((object)("[Spookbox]: " + info));
		}

		public static void LogError(string error)
		{
			Debug.LogError((object)("[Spookbox]: " + error));
		}

		public static void LogWarning(string warning)
		{
			Debug.LogWarning((object)("[Spookbox]: " + warning));
		}
	}
	public static class Mixtape
	{
		public const string ASYNC_LOAD_ENV = "-ihaveanssd";

		public const string TRACKS_DIR_NAME = "SpookboxMixtape";

		public const int MAX_TRACKS = 255;

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

		public static Action OnUnLoad;

		public static Action OnLoad;

		private static bool _isLoading = false;

		private static bool _asyncLoadTracks => Environment.GetCommandLineArgs().Contains("-ihaveanssd");

		public static int Length => Tracks.Count;

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

		public static void Load()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Invalid comparison between Unknown and I4
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			Logger.Log("Loading mixtape!");
			if (_isLoading)
			{
				Logger.LogWarning("Spookbox mixtape is already loading tracks.");
				return;
			}
			_isLoading = true;
			Logger.Log(string.Format("Async load audio clips ({0} flag) : {1}", "-ihaveanssd", _asyncLoadTracks));
			Unload();
			List<string> allTracks = GetAllTracks();
			Logger.Log($"{allTracks.Count} potential mixtape tracks found.");
			foreach (string item in allTracks)
			{
				if (Tracks.Count == 255)
				{
					Logger.LogWarning($"Mixtape full: maximum track count limit reached ({255}).");
					break;
				}
				AudioType audioType = GetAudioType(item);
				if ((int)audioType == 0)
				{
					Logger.LogWarning("Track \"" + item + "\" could not be loaded due to unsupported audio type.");
					continue;
				}
				AudioClip val = LoadAudioClipFromFile(item, GetAudioType(item));
				if ((Object)(object)val == (Object)null)
				{
					Logger.LogWarning("Track \"" + item + "\" skipped due to an error.");
					continue;
				}
				((Object)val).name = Path.GetFileNameWithoutExtension(item);
				Tracks.Add(val);
				Logger.Log("Added track to mixtape: " + ((Object)val).name);
			}
			Logger.Log($"Loaded {Tracks.Count} tracks to the Mixtape.");
			_isLoading = false;
			OnLoad?.Invoke();
		}

		public static void Unload()
		{
			Logger.Log("Unloading mixtape!");
			OnUnLoad?.Invoke();
			foreach (AudioClip track in Tracks)
			{
				track.UnloadAudioData();
			}
			Tracks.Clear();
		}

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

		internal 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_0031: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			AudioClip result = null;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, type);
			if (_asyncLoadTracks)
			{
				((DownloadHandlerAudioClip)audioClip.downloadHandler).streamAudio = true;
			}
			else
			{
				((DownloadHandlerAudioClip)audioClip.downloadHandler).compressed = true;
			}
			try
			{
				audioClip.SendWebRequest();
				try
				{
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result == 1)
					{
						AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
						if (content.length != 0f)
						{
							result = content;
						}
					}
					else
					{
						Logger.LogError("Loading AudioClip from " + path + " failed: " + audioClip.error);
					}
				}
				catch (Exception ex)
				{
					Logger.LogError("Loading AudioClip failed:");
					Debug.LogException(ex);
				}
			}
			catch (Exception ex2)
			{
				Logger.LogError("Request for " + path + " failed:");
				Debug.LogException(ex2);
			}
			finally
			{
				if (audioClip != null)
				{
					audioClip.Dispose();
				}
			}
			return result;
		}
	}
	[ContentWarningPlugin("xerren.cwspookbox", "1.3.0.0", false)]
	[BepInPlugin("xerren.cwspookbox", "Spöökbox", "1.3.0.0")]
	[BepInDependency("xerren.cwshopapi", "1.3.0.0")]
	public class PluginLoader : BaseUnityPlugin
	{
		private static Harmony harmony = new Harmony("xerren.cwspookbox");

		private void Awake()
		{
			Logger.Log("Loading via BepInEx mod loader.");
			SpookboxPlugin.InitialisePlugin();
			harmony.PatchAll();
			Logger.Log("Finished loading.");
		}
	}
	[HarmonyPatch(typeof(GameHandler))]
	internal class GameHandlerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Initialize")]
		private static void Initialize()
		{
			SpookboxPlugin.RegisterSettings();
		}
	}
	public class SpookboxPlugin
	{
		public const string MOD_GUID = "xerren.cwspookbox";

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

		public const string MOD_VER = "1.3.0.0";

		private const string ASSETBUNDLE_NAME = "spookbox";

		internal static AssetBundle? _bundle;

		internal static Item? _spookboxItem;

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

		private static Callback<LobbyCreated_t> cb_onLobbyCreated;

		private const string ALERT_META_GUID = "bigslapTunes";

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

		private const string INF_BATTERY_META_GUID = "infiniteBattery";

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

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

		internal static void InitialisePlugin()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (cb_onLobbyCreated == null)
			{
				string text = Path.Join(MemoryExtensions.AsSpan(PluginDirPath), MemoryExtensions.AsSpan("spookbox"));
				_bundle = AssetBundle.LoadFromFile(text);
				_spookboxItem = _bundle.LoadAsset<Item>("Spookbox");
				_spookboxItem.itemObject.AddComponent<SpookboxBehaviour>();
				ShopLocalisation.SetDefaultTooltips(_spookboxItem, ShopLocalisation.UseGlyph + " Play;" + ShopLocalisation.ZoomGlyph + " Select Track");
				Shop.RegisterItem(_spookboxItem);
				Shop.RegisterCustomDataEntries();
				Mixtape.Load();
				cb_onLobbyCreated = Callback<LobbyCreated_t>.Create((DispatchDelegate<LobbyCreated_t>)Steam_LobbyCreated);
				Logger.Log("Setup complete.");
			}
		}

		internal static void RegisterSettings()
		{
			RegisterGameSetting<BoomboxLocalVolumeSetting>();
			RegisterGameSetting<BoomboxVolumeUpBindSetting>();
			RegisterGameSetting<BoomboxVolumeDownBindSetting>();
			RegisterGameSetting<BoomboxAlertSetting>();
			RegisterGameSetting<BoomboxInfiniteBatterySetting>();
			RegisterGameSetting<BoomboxPriceSetting>();
			RegisterGameSetting<BoomboxOpenTracksFolderSetting>();
			RegisterGameSetting<BoomboxRescanMixtapeFolderSetting>();
			Logger.Log("Settings registered.");
		}

		private static void Steam_LobbyCreated(LobbyCreated_t e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)e.m_eResult == 1)
			{
				ApplyGameSetting<BoomboxAlertSetting>();
				ApplyGameSetting<BoomboxInfiniteBatterySetting>();
				ApplyGameSetting<BoomboxPriceSetting>();
			}
		}

		private static void RegisterGameSetting<T>() where T : Setting, new()
		{
			if (GameHandler.Instance.SettingsHandler.GetSetting<T>() == null)
			{
				GameHandler.Instance.SettingsHandler.AddSetting((Setting)(object)new T());
			}
		}

		private static void ApplyGameSetting<T>() where T : Setting, new()
		{
			T setting = GameHandler.Instance.SettingsHandler.GetSetting<T>();
			if (setting != null)
			{
				((Setting)setting).ApplyValue();
			}
		}
	}
}
namespace Spookbox.Settings
{
	public abstract class ButtonSetting : Setting
	{
		public override SettingUI GetDebugUI(ISettingHandler settingHandler)
		{
			return (SettingUI)(object)new ButtonSettingUI(OnClick, GetButtonText());
		}

		public override GameObject GetSettingUICell()
		{
			GameObject keyCodeSettingCell = SingletonAsset<InputCellMapper>.Instance.KeyCodeSettingCell;
			GameObject val = Object.Instantiate<GameObject>(keyCodeSettingCell);
			KeyCodeSettingUI component = val.GetComponent<KeyCodeSettingUI>();
			Object.DestroyImmediate((Object)(object)component);
			val.AddComponent<ButtonInputSettingUI>();
			return val;
		}

		public abstract string GetButtonText();

		public abstract void OnClick();
	}
	public class ButtonSettingUI : SettingUI
	{
		private Button _button;

		public ButtonSettingUI(Action OnClick, string text)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			_button = new Button(OnClick);
			((TextElement)_button).text = text;
		}
	}
	public class ButtonInputSettingUI : SettingInputUICell
	{
		private Button _button;

		private ButtonSetting _setting;

		public override void Setup(Setting setting, ISettingHandler settingHandler)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			if (!(setting is ButtonSetting))
			{
				return;
			}
			_setting = setting as ButtonSetting;
			_button = ((Component)this).gameObject.GetComponentInChildren<Button>();
			if (setting is ButtonSetting buttonSetting)
			{
				TextMeshProUGUI componentInChildren = ((Component)_button).GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = buttonSetting.GetButtonText();
				}
			}
			((UnityEvent)_button.onClick).AddListener(new UnityAction(OnClick));
		}

		private void OnClick()
		{
			_setting.OnClick();
		}
	}
	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;
					}
				}
			}
		}
	}
	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;
		}
	}
	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;
		}
	}
	public class BoomboxAlertSetting : BoolSetting, IExposedSetting
	{
		public override void ApplyValue()
		{
			SpookboxPlugin.AlertMonsters.SetValue(((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;
		}
	}
	public class BoomboxInfiniteBatterySetting : BoolSetting, IExposedSetting
	{
		public override void ApplyValue()
		{
			SpookboxPlugin.InfiniteBattery.SetValue(((BoolSetting)this).Value);
		}

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

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

		public override bool GetDefaultValue()
		{
			return false;
		}
	}
	public class BoomboxPriceSetting : IntSetting, IExposedSetting
	{
		public override void ApplyValue()
		{
			if (!((Object)(object)SpookboxPlugin._spookboxItem == (Object)null) && !Shop.UpdateItemPrice(SpookboxPlugin._spookboxItem, ((IntSetting)this).Value))
			{
				Logger.LogWarning("Attempted to apply BoomboxPriceSetting value to item while not the host of the current lobby.");
			}
		}

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

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

		public override int GetDefaultValue()
		{
			return 100;
		}
	}
	public class BoomboxOpenTracksFolderSetting : ButtonSetting, IExposedSetting
	{
		public override string GetButtonText()
		{
			return "Open";
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Open music folder";
		}

		public override void OnClick()
		{
			Logger.Log("Opening music dir: " + Mixtape.GetPluginMusicDirPath());
			Process.Start("explorer.exe", Mixtape.GetPluginMusicDirPath());
		}

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

		public override void ApplyValue()
		{
		}

		public override void Load(ISettingsSaveLoad loader)
		{
		}

		public override void Save(ISettingsSaveLoad saver)
		{
		}
	}
	public class BoomboxRescanMixtapeFolderSetting : ButtonSetting, IExposedSetting
	{
		public override string GetButtonText()
		{
			return "Rescan";
		}

		public string GetDisplayName()
		{
			return "[Spöökbox] Reload music";
		}

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

		public override void OnClick()
		{
			Mixtape.Load();
		}

		public override void ApplyValue()
		{
		}

		public override void Load(ISettingsSaveLoad loader)
		{
		}

		public override void Save(ISettingsSaveLoad saver)
		{
		}
	}
}
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
			{
				if (Mixtape.Tracks.Count != 0)
				{
					_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 void UpdateLocale()
		{
		}
	}
	public class VolumeEntry : ItemDataEntry, IHaveUIData
	{
		public const string VOLUME_LOC_KEY_NAME = "spookbox_volume";

		private string _labelText = "Volume";

		private float _volume = 0f;

		public const float MaxVolume = 1f;

		public string UIString = "{0}% {1}";

		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 string.Format(UIString, Mathf.RoundToInt(Volume * 100f), _labelText);
		}

		public void UpdateLocale()
		{
			string labelText = default(string);
			if (ShopLocalisation.TryGetLocaleString("spookbox_volume", ref labelText))
			{
				_labelText = labelText;
			}
		}
	}
}
namespace Spookbox.Behaviour
{
	public class SpookboxBehaviour : ItemInstanceBehaviour
	{
		private static readonly string INPUTACTIONREF_SOURCE_ITEM_PERSISTENT_GUID = "76f4d02a-65ae-4d8b-89da-1e3e1e82f82d";

		private static readonly float INPUT_DEBOUNCE_TIME = 0.15f;

		private static InputActionReference ZoomIn;

		private static InputActionReference ZoomOut;

		private static AudioClip EMPTY_CLIP = new AudioClip();

		private bool _ready = false;

		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 static readonly int DEFAULT_ALERT_DISTANCE = 35;

		private static readonly float ALERT_INTERVAL = 0.15f;

		private float _alertCountdown = 0f;

		private int _trackIndex = -1;

		private float _instanceVolume = 0.5f;

		private float _inputDebounceTimer = 0f;

		private bool isPlaying => _speaker.isPlaying;

		private bool isOn => _onOffEntry.on;

		private void Awake()
		{
			if ((Object)(object)ZoomIn == (Object)null)
			{
				Item val = default(Item);
				ItemDatabase.TryGetItemFromPersistentID(new Guid(INPUTACTIONREF_SOURCE_ITEM_PERSISTENT_GUID), ref val);
				VideoCamera component = val.itemObject.GetComponent<VideoCamera>();
				ZoomIn = component.m_cameraZoomIn;
				ZoomOut = component.m_cameraZoomOut;
			}
			_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;
			Mixtape.OnLoad = (Action)Delegate.Combine(Mixtape.OnLoad, new Action(_onMixtapeLoad));
			Mixtape.OnUnLoad = (Action)Delegate.Combine(Mixtape.OnUnLoad, new Action(_onMixtapeUnLoad));
			_localVolumeSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxLocalVolumeSetting>();
			_localVolumeSetting.Changed += _localVolumeSetting_Changed;
			_volumeUpBindSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxVolumeUpBindSetting>();
			_volumeDownBindSetting = GameHandler.Instance.SettingsHandler.GetSetting<BoomboxVolumeDownBindSetting>();
		}

		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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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<TimeEntry>(ref _playbackTime))
			{
				_playbackTime = new TimeEntry
				{
					currentTime = 0f
				};
				data.AddDataEntry((ItemDataEntry)(object)_playbackTime);
			}
			if (!data.TryGetEntry<TrackEntry>(ref _track))
			{
				_track = new TrackEntry();
				data.AddDataEntry((ItemDataEntry)(object)_track);
			}
			base.itemInstance.onItemEquipped.AddListener((UnityAction<Player>)OnEquip);
			base.itemInstance.onUnequip.AddListener((UnityAction<Player>)OnUnequip);
			_ready = true;
		}

		private void Update()
		{
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			if (!_ready)
			{
				return;
			}
			_inputDebounceTimer += Time.deltaTime;
			if (base.isHeldByMe && !Player.localPlayer.HasLockedInput() && GlobalInputHandler.CanTakeInput())
			{
				if (Player.localPlayer.input.clickWasPressed)
				{
					_onOffEntry.on = !_onOffEntry.on;
					((ItemDataEntry)_onOffEntry).SetDirty();
					if (_onOffEntry.on && SpookboxPlugin.AlertMonsters.Value)
					{
						_alertCountdown = ALERT_INTERVAL;
					}
					PlayClickButtonSFX();
				}
				float axisRaw = Input.GetAxisRaw("Mouse ScrollWheel");
				if ((_inputDebounceTimer > INPUT_DEBOUNCE_TIME && axisRaw > 0f) || ZoomOut.action.WasPressedThisFrame())
				{
					_inputDebounceTimer = 0f;
					int num = ((_track.TrackIndex == 0) ? (Mixtape.Tracks.Count - 1) : (_track.TrackIndex - 1));
					SetTrack(num % Mixtape.Tracks.Count);
					PlayClickButtonSFX();
				}
				else if ((_inputDebounceTimer > INPUT_DEBOUNCE_TIME && axisRaw < 0f) || ZoomIn.action.WasPressedThisFrame())
				{
					_inputDebounceTimer = 0f;
					SetTrack((_track.TrackIndex + 1) % Mixtape.Tracks.Count);
					PlayClickButtonSFX();
				}
				if (GlobalInputHandler.GetKeyUp(((KeyCodeSetting)_volumeUpBindSetting).Keycode()))
				{
					_volume.Volume += 0.1f;
					((ItemDataEntry)_volume).SetDirty();
					AdjustVolume();
					PlayClickButtonSFX();
				}
				if (GlobalInputHandler.GetKeyUp(((KeyCodeSetting)_volumeDownBindSetting).Keycode()))
				{
					_volume.Volume -= 0.1f;
					((ItemDataEntry)_volume).SetDirty();
					AdjustVolume();
					PlayClickButtonSFX();
				}
			}
			if (_instanceVolume != _volume.Volume)
			{
				AdjustVolume();
				PlayClickButtonSFX();
			}
			if (_trackIndex != _track.TrackIndex)
			{
				SetTrack(_track.TrackIndex, _playbackTime.currentTime);
				if (base.isHeld && !base.isHeldByMe)
				{
					PlayClickButtonSFX();
				}
			}
			if (_onOffEntry.on != _speaker.isPlaying)
			{
				if (_onOffEntry.on)
				{
					TryStartPlayback();
				}
				else
				{
					TryStopPlayback();
				}
				if (base.isHeld && !base.isHeldByMe)
				{
					PlayClickButtonSFX();
				}
			}
			if (!_onOffEntry.on)
			{
				return;
			}
			if (!SpookboxPlugin.InfiniteBattery.Value)
			{
				BatteryEntry battery = _battery;
				battery.m_charge -= Time.deltaTime;
			}
			if (SpookboxPlugin.AlertMonsters.Value)
			{
				_alertCountdown -= Time.deltaTime;
				if (_alertCountdown < 0f)
				{
					float num2 = (float)DEFAULT_ALERT_DISTANCE * _volume.Volume;
					SFX_Player.instance.PlayNoise(((Component)this).transform.position, num2, 1);
					_alertCountdown = ALERT_INTERVAL;
				}
			}
			if (_battery.m_charge < 0f)
			{
				_onOffEntry.on = false;
				((ItemDataEntry)_onOffEntry).SetDirty();
				PlayClickButtonSFX();
			}
			else
			{
				_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);
			Mixtape.OnLoad = (Action)Delegate.Remove(Mixtape.OnLoad, new Action(_onMixtapeLoad));
			Mixtape.OnUnLoad = (Action)Delegate.Remove(Mixtape.OnUnLoad, new Action(_onMixtapeUnLoad));
		}

		private void OnEquip(Player player)
		{
			if (TryReattachSpeaker(player))
			{
				Logger.Log($"Speaker reattached: {base.itemInstance.instanceData.m_guid}");
			}
			SetTrack(_track.TrackIndex, _playbackTime.currentTime);
			TryStartPlayback();
		}

		private void OnUnequip(Player player)
		{
			if (IsItemInPlayerInventory(player, base.itemInstance.instanceData.m_guid) && _onOffEntry.on)
			{
				DetachSpeaker(player);
				Logger.Log($"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 TryGetDetachedSpeaker(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(player, _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 val = TryGetDetachedSpeaker(player);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			AudioSource component = val.GetComponent<AudioSource>();
			_playbackTime.currentTime = component.time;
			Object.Destroy((Object)(object)val);
			return true;
		}

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

		private void _onMixtapeLoad()
		{
			SetTrack(_track.TrackIndex, _playbackTime.currentTime);
			if (_onOffEntry.on)
			{
				TryStartPlayback();
			}
		}

		private void _onMixtapeUnLoad()
		{
			bool on = _onOffEntry.on;
			_onOffEntry.on = false;
			TryStopPlayback();
			_speaker.clip = EMPTY_CLIP;
			_onOffEntry.on = on;
		}

		private void SetTrack(int idx, float trackTime = 0f)
		{
			if (!Mixtape.HasTracks())
			{
				return;
			}
			idx = Math.Clamp(idx, 0, Mixtape.Tracks.Count - 1);
			AudioClip val = Mixtape.Tracks[idx];
			if (!((Object)(object)val == (Object)(object)_speaker.clip))
			{
				if (base.isHeldByMe)
				{
					_playbackTime.currentTime = trackTime;
					((ItemDataEntry)_playbackTime).SetDirty();
					_track.TrackIndex = idx;
					((ItemDataEntry)_track).SetDirty();
				}
				_speaker.clip = val;
				_speaker.time = trackTime;
				_trackIndex = idx;
			}
		}

		private bool TryStartPlayback(bool resume = true)
		{
			if (!_speaker.isPlaying && _onOffEntry.on)
			{
				_speaker.Play();
				if (resume)
				{
					_speaker.time = _playbackTime.currentTime;
				}
				return true;
			}
			return false;
		}

		private bool TryStopPlayback()
		{
			if (_speaker.isPlaying && !_onOffEntry.on)
			{
				_speaker.Stop();
				return true;
			}
			return false;
		}

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

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

		private OnOffEntry _onOffEntry;

		private BatteryEntry _batteryEntry;

		private float _volume;

		private AudioSource _speaker;

		private BoomboxLocalVolumeSetting _localVolumeSetting;

		private static readonly int DEFAULT_ALERT_DISTANCE = 35;

		private static readonly float ALERT_INTERVAL = 0.15f;

		private float _alertCountdown = 0f;

		public Player Owner => _owner;

		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(Player owner, OnOffEntry onOff, BatteryEntry battery, float volume)
		{
			_owner = owner;
			_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()
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (!SpookboxPlugin.InfiniteBattery.Value)
			{
				if (_batteryEntry.m_charge < 0f)
				{
					_onOffEntry.on = false;
					((ItemDataEntry)_onOffEntry).SetDirty();
					Logger.Log("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;
			}
			if (SpookboxPlugin.AlertMonsters.Value)
			{
				_alertCountdown -= Time.deltaTime;
				if (_alertCountdown < 0f)
				{
					float num = (float)DEFAULT_ALERT_DISTANCE * _volume;
					SFX_Player.instance.PlayNoise(((Component)this).transform.position, num, 1);
					_alertCountdown = ALERT_INTERVAL;
				}
			}
			if (_owner.data.dead)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}