Decompiled source of Boombox Playlists v1.0.1

BoomboxPlaylists.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BoomboxPlaylists.Managers;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BoomboxPlaylists")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BoomboxPlaylists")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("020a0457-0d96-492e-ad0f-548bc97b9557")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BoomboxPlaylists
{
	[BepInPlugin("Batres3.BoomboxPlaylists", "Boombox Playlists", "1.0.0")]
	public class BoomboxPlaylistsBase : BaseUnityPlugin
	{
		private const string modGUID = "Batres3.BoomboxPlaylists";

		private const string modName = "Boombox Playlists";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("Batres3.BoomboxPlaylists");

		private static BoomboxPlaylistsBase Instance;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			if (!Directory.Exists(Path.Combine(Paths.BepInExRootPath, "Custom Playlists")))
			{
				Directory.CreateDirectory(Path.Combine(Paths.BepInExRootPath, "Custom Playlists"));
				LogError("No custom playlists detected, they must be in the 'Custom Playlists' folder");
			}
			else
			{
				harmony.PatchAll();
				AudioManager.Load();
				LogInfo("Boombox Playlists Loaded!");
			}
		}

		internal static void LogInfo(string message)
		{
			Instance.Log(message, (LogLevel)16);
		}

		internal static void LogError(string message)
		{
			Instance.Log(message, (LogLevel)2);
		}

		private void Log(string message, LogLevel logLevel)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.Log(logLevel, (object)message);
		}
	}
}
namespace BoomboxPlaylists.Utils
{
	internal class SharedCoroutineStarter : MonoBehaviour
	{
		private static SharedCoroutineStarter _instance;

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = new GameObject("Shared Coroutine Starter").AddComponent<SharedCoroutineStarter>();
				Object.DontDestroyOnLoad((Object)(object)_instance);
			}
			return ((MonoBehaviour)_instance).StartCoroutine(routine);
		}
	}
}
namespace BoomboxPlaylists.Patches
{
	[HarmonyPatch(typeof(BoomboxItem))]
	internal class BoomboxItemPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Start_Postfix(BoomboxItem __instance)
		{
			if (AudioManager.finishedLoading)
			{
				AudioManager.ApplyClips(ref __instance);
				return;
			}
			AudioManager.OnAllSongsLoaded += delegate
			{
				AudioManager.ApplyClips(ref __instance);
			};
			AudioManager.SetTooltip(ref __instance);
		}

		[HarmonyPatch("StartMusic")]
		[HarmonyPostfix]
		private static void StartMusic_Postfix(BoomboxItem __instance, bool startMusic)
		{
			AudioManager.SetVolume(ref __instance);
			AudioManager.NextSong(ref __instance, ref startMusic);
		}

		[HarmonyPatch("PocketItem")]
		[HarmonyPostfix]
		private static void PocketItem_Postfix(BoomboxItem __instance)
		{
			AudioManager.ApplyClips(ref __instance);
			AudioManager.SetTooltip(ref __instance);
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void Update_Postfix(BoomboxItem __instance)
		{
			if (((GrabbableObject)__instance).isHeld)
			{
				if (((KeyboardShortcut)(ref AudioManager.lowerVolume)).IsPressed())
				{
					AudioManager.ModifyVolume(increase: false, ref __instance);
				}
				else if (((KeyboardShortcut)(ref AudioManager.increaseVolume)).IsPressed())
				{
					AudioManager.ModifyVolume(increase: true, ref __instance);
				}
			}
		}
	}
}
namespace BoomboxPlaylists.Managers
{
	internal static class AudioManager
	{
		public static List<PlaylistManager> playlistManagers = new List<PlaylistManager>();

		public static int currentPlaylistID;

		public static bool finishedLoading = false;

		public static int currentSongID = 0;

		private static readonly string directory = Path.Combine(Paths.BepInExRootPath, "Custom Playlists");

		private static readonly string[] defaultTooltip = new string[3] { "Toggle Music : [LMB]", "Playlist : ", "Change Volume : [Ctrl]+[Shift]+[K]/[J]" };

		private static KeyCode[] conditionKeys = (KeyCode[])(object)new KeyCode[2]
		{
			(KeyCode)304,
			(KeyCode)306
		};

		public static KeyboardShortcut lowerVolume = new KeyboardShortcut((KeyCode)106, conditionKeys);

		public static KeyboardShortcut increaseVolume = new KeyboardShortcut((KeyCode)107, conditionKeys);

		public static float volume = 1f;

		public static event Action OnAllSongsLoaded;

		public static void Load()
		{
			if (playlistManagers.Count != 0)
			{
				return;
			}
			string[] array = Directory.GetDirectories(directory).Select(Path.GetFileName).ToArray();
			if (array.Length == 0)
			{
				BoomboxPlaylistsBase.LogError("No playlists detected");
				return;
			}
			string[] array2 = array;
			foreach (string playlistname in array2)
			{
				playlistManagers.Add(new PlaylistManager(playlistname));
			}
			int num = 0;
			foreach (PlaylistManager playlistManager in playlistManagers)
			{
				array2 = playlistManager.playlistSongsPaths;
				for (int i = 0; i < array2.Length; i++)
				{
					LoadAudioClip(array2[i], num);
				}
				BoomboxPlaylistsBase.LogInfo("Loaded playlist " + playlistManager.playlistName);
				num++;
			}
		}

		private static void LoadAudioClip(string filePath, int playlistID)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Invalid comparison between Unknown and I4
			if ((int)GetAudioType(filePath) == 0)
			{
				BoomboxPlaylistsBase.LogError("Failed to load AudioClip from " + filePath + "!");
				return;
			}
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(filePath, GetAudioType(filePath));
			audioClip.SendWebRequest();
			while (!audioClip.isDone)
			{
			}
			if (audioClip.error != null)
			{
				BoomboxPlaylistsBase.LogError("Error loading clip from path: " + filePath);
				BoomboxPlaylistsBase.LogError(audioClip.error);
				return;
			}
			AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
			if (Object.op_Implicit((Object)(object)content) && (int)content.loadState == 2)
			{
				((Object)content).name = Path.GetFileName(filePath);
				BoomboxPlaylistsBase.LogInfo("Loaded song " + ((Object)content).name);
				playlistManagers[playlistID].clips.Add(content);
			}
			else
			{
				BoomboxPlaylistsBase.LogError("Failed to load clip at: " + filePath + "\nThis might be due to an mismatch between the audio codec and the file extension!");
			}
		}

		private static IEnumerator WaitForAllClips(List<Coroutine> coroutines, int playlistID)
		{
			foreach (Coroutine coroutine in coroutines)
			{
				yield return coroutine;
			}
			playlistManagers[playlistID].clips.Sort((AudioClip first, AudioClip second) => ((Object)first).name.CompareTo(((Object)second).name));
			finishedLoading = true;
			AudioManager.OnAllSongsLoaded?.Invoke();
			AudioManager.OnAllSongsLoaded = null;
		}

		private static AudioType GetAudioType(string filePath)
		{
			string extension = Path.GetExtension(filePath);
			switch (extension)
			{
			case ".wav":
				return (AudioType)20;
			case ".ogg":
				return (AudioType)14;
			case ".mp3":
				return (AudioType)13;
			default:
				BoomboxPlaylistsBase.LogError("Unsupported extesion type: " + extension);
				return (AudioType)0;
			}
		}

		public static void ApplyClips(ref BoomboxItem __istance)
		{
			currentPlaylistID++;
			if (currentPlaylistID >= playlistManagers.Count)
			{
				currentPlaylistID = 0;
			}
			currentSongID = 0;
			__istance.musicAudios = playlistManagers[currentPlaylistID].clips.ToArray();
		}

		public static void SetTooltip(ref BoomboxItem __instance)
		{
			string[] array = new string[3];
			Array.Copy(defaultTooltip, array, defaultTooltip.Length);
			array[1] += playlistManagers[currentPlaylistID].playlistName;
			((GrabbableObject)__instance).itemProperties.toolTips = array;
		}

		public static void ModifyVolume(bool increase, ref BoomboxItem __instance)
		{
			if (increase)
			{
				volume = Mathf.Clamp(volume + 0.01f, 0f, 1f);
				SetVolume(ref __instance);
			}
			else
			{
				volume = Mathf.Clamp(volume - 0.01f, 0f, 1f);
				SetVolume(ref __instance);
			}
		}

		public static void SetVolume(ref BoomboxItem __instance)
		{
			__instance.boomboxAudio.volume = volume;
		}

		public static void NextSong(ref BoomboxItem __instance, ref bool startMusic)
		{
			if (startMusic)
			{
				currentSongID++;
				if (currentSongID >= playlistManagers[currentPlaylistID].clips.Count)
				{
					currentSongID = 0;
				}
				__instance.boomboxAudio.clip = __instance.musicAudios[currentSongID];
				__instance.boomboxAudio.pitch = 1f;
				__instance.boomboxAudio.Play();
				startMusic = false;
			}
		}
	}
	internal class PlaylistManager
	{
		public string[] playlistSongsPaths;

		public List<AudioClip> clips = new List<AudioClip>();

		private readonly string playlistPath;

		public string playlistName;

		public bool hasNoSongs => playlistSongsPaths.Length == 0;

		internal PlaylistManager(string playlistname)
		{
			playlistName = playlistname;
			playlistPath = Path.Combine(Paths.BepInExRootPath, "Custom Playlists", playlistName);
			playlistSongsPaths = Directory.GetFiles(playlistPath);
			if (hasNoSongs)
			{
				BoomboxPlaylistsBase.LogError("No songs found for playlist " + playlistName);
			}
		}
	}
}