Decompiled source of Spookbox v1.1.0

Spookbox.dll

Decompiled 2 months 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.1.32.56348")]
[assembly: AssemblyInformationalVersion("1.1.32+dc1c10cb1c")]
[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")]
[assembly: AssemblyProduct("Spookbox")]
[assembly: AssemblyTitle("Spookbox")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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.1.32.56348";

	internal const string AssemblyInformationalVersion = "1.1.32+dc1c10cb1c";

	internal const string AssemblyName = "Spookbox";

	internal const string AssemblyTitle = "Spookbox";

	internal const string AssemblyVersion = "1.1.0.0";

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

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

	internal const string GitCommitId = "dc1c10cb1c14f1754840e4136e169bc519c14d81";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string RootNamespace = "Spookbox";
}
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";

		public const int MAX_TRACKS = 255;

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

		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 LoadTracks()
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Invalid comparison between Unknown and I4
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			if (_isLoading)
			{
				Debug.LogWarning((object)"Spookbox mixtape is already loading tracks.");
				return;
			}
			_isLoading = true;
			Debug.Log((object)string.Format("Async load audio clips ({0} flag) : {1}", "-ihaveanssd", _asyncLoadTracks));
			foreach (AudioClip track in Tracks)
			{
				track.UnloadAudioData();
			}
			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)
				{
					Debug.LogWarning((object)("Track \"" + item + "\" skipped due to an error."));
					continue;
				}
				((Object)val).name = Path.GetFileNameWithoutExtension(item);
				Tracks.Add(val);
				Debug.Log((object)("Added track to mixtape: " + ((Object)val).name));
			}
			Debug.Log((object)$"Loaded {Tracks.Count} tracks to the Mixtape.");
			_isLoading = false;
		}

		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
					{
						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.1.0.0", false)]
	[BepInPlugin("xerren.cwspookbox", "Spöökbox", "1.1.0.0")]
	[BepInDependency("xerren.cwshopapi", "1.2")]
	public class PluginLoader : BaseUnityPlugin
	{
		private static Harmony harmony = new Harmony("xerren.cwspookbox");

		private void Awake()
		{
			Debug.Log((object)"xerren.cwspookbox loading via BepInEx mod loader.");
			harmony.PatchAll();
			try
			{
				Action action = delegate
				{
					SpookboxPlugin.InitialisePlugin();
				};
				action();
			}
			catch (TypeLoadException ex)
			{
				bool flag = IsShopApiAssemblyLoaded();
				Debug.LogError((object)string.Format("{0} failed to load due to missing Types: missing ShopAPI? {1}", "xerren.cwspookbox", !flag));
				Debug.LogException((Exception)ex);
				if (flag)
				{
					ShowMissingDependencyRestartPrompt();
				}
			}
			catch (Exception ex2)
			{
				Debug.LogError((object)string.Format("{0} failed: missing ShopAPI? {1}", "xerren.cwspookbox", !IsShopApiAssemblyLoaded()));
				Debug.LogException(ex2);
				ShowGenericRestartPrompt();
			}
			Debug.Log((object)"xerren.cwspookbox loaded.");
		}

		private static bool IsShopApiAssemblyLoaded()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly assembly = Array.Find(assemblies, (Assembly a) => a.GetName().Name == "ShopAPI");
			return assembly != null;
		}

		private static void ShowMissingDependencyRestartPrompt()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ModalOption[] array = (ModalOption[])(object)new ModalOption[1]
			{
				new ModalOption("Close Game", (Action)null)
			};
			Modal.Show("Spöökbox Dependency Error", "Spöökbox depends on the ShopAPI mod, which is missing. This can often be caused by installing the mod while the game is running. Please ensure you've subscribed to the ShopAPI mod, and restart your game. If you run into further issues please read the Workshop page, and don't hesitate to reach out.", array, (Action)delegate
			{
				Application.Quit();
			});
		}

		private static void ShowGenericRestartPrompt()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ModalOption[] array = (ModalOption[])(object)new ModalOption[1]
			{
				new ModalOption("OK", (Action)null)
			};
			Modal.Show("Spöökbox Load Error", "Spöökbox encountered an error while loading. This can often be caused by installing the mod while the game is running. Please ensure you've subscribed to the ShopAPI mod, and restart your game. If you run into further issues please read the Workshop page, and don't hesitate to reach out.", array, (Action)null);
		}
	}
	public class SpookboxPlugin
	{
		public const string MOD_GUID = "xerren.cwspookbox";

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

		public const string MOD_VER = "1.1.0.0";

		private const string ASSETBUNDLE_NAME = "spookbox";

		private static bool _initialised = false;

		private static bool _initialisedSettings = false;

		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()
		{
			if (!_initialised)
			{
				LoadAssetBundle();
				_spookboxItem = _bundle.LoadAsset<Item>("Spookbox");
				_spookboxItem.itemObject.AddComponent<SpookboxBehaviour>();
				Shop.RegisterItem(_spookboxItem);
				Shop.RegisterCustomDataEntries();
				ShopLocalisation.SetDefaultTooltips(_spookboxItem, ShopLocalisation.UseGlyph + " Play;" + ShopLocalisation.ZoomGlyph + " Select Track");
				Mixtape.LoadTracks();
				_initialised = true;
				Debug.Log((object)"xerren.cwspookbox setup complete.");
			}
		}

		internal static void InitialiseSettings()
		{
			if (!_initialisedSettings)
			{
				cb_onLobbyCreated = Callback<LobbyCreated_t>.Create((DispatchDelegate<LobbyCreated_t>)Steam_LobbyCreated);
				InitialiseGameSetting<BoomboxAlertSetting>();
				InitialiseGameSetting<BoomboxInfiniteBatterySetting>();
				InitialiseGameSetting<BoomboxPriceSetting>();
				InitialiseGameSetting<BoomboxOpenTracksFolderSetting>();
				InitialiseGameSetting<BoomboxRescanMixtapeFolderSetting>();
				_initialisedSettings = true;
				Debug.Log((object)"xerren.cwspookbox settings initialised.");
			}
		}

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

		private static void 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"));
			_bundle = AssetBundle.LoadFromFile(text);
		}
	}
}
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();
		}
	}
	[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 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;
		}
	}
	[ContentWarningSetting]
	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;
		}
	}
	[ContentWarningSetting]
	public class BoomboxPriceSetting : IntSetting, IExposedSetting
	{
		public override void ApplyValue()
		{
			if (!((Object)(object)SpookboxPlugin._spookboxItem == (Object)null) && !Shop.UpdateItemPrice(SpookboxPlugin._spookboxItem, ((IntSetting)this).Value))
			{
				Debug.LogWarning((object)"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;
		}
	}
	[ContentWarningSetting]
	public class BoomboxOpenTracksFolderSetting : ButtonSetting, IExposedSetting
	{
		public override string GetButtonText()
		{
			return "Open";
		}

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

		public override void OnClick()
		{
			Debug.Log((object)("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)
		{
		}
	}
	[ContentWarningSetting]
	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.LoadTracks();
		}

		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 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 static readonly string INPUTACTIONREF_SOURCE_ITEM_PERSISTENT_GUID;

		private static readonly float INPUT_DEBOUNCE_TIME;

		private static InputActionReference ZoomIn;

		private static InputActionReference ZoomOut;

		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;

		private static readonly float ALERT_INTERVAL;

		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;

		static SpookboxBehaviour()
		{
			INPUTACTIONREF_SOURCE_ITEM_PERSISTENT_GUID = "76f4d02a-65ae-4d8b-89da-1e3e1e82f82d";
			INPUT_DEBOUNCE_TIME = 0.15f;
			DEFAULT_ALERT_DISTANCE = 35;
			ALERT_INTERVAL = 0.15f;
			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;
		}

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

		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_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: 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 (Player.localPlayer.input.aimWasPressed)
				{
					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);
		}

		private void OnEquip(Player player)
		{
			if (TryReattachSpeaker(player))
			{
				Debug.Log((object)$"Spöökbox 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);
				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 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(_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 SetTrack(int idx, float trackTime = 0f)
		{
			if (!Mixtape.HasTracks())
			{
				return;
			}
			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 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;

		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()
		{
			//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();
					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;
			}
			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;
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}