Decompiled source of MoreMusicMod v1.0.2

plugins/MoreMusicMod.dll

Decompiled a year 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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreMusicMod.Configuration;
using MoreMusicMod.Helpers;
using MoreMusicMod.Patches;
using MoreMusicMod.Services;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MoreMusicMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+f861f30b8f892d1b09eb0702dc5bc81a0c4a9fa7")]
[assembly: AssemblyProduct("MoreMusicMod")]
[assembly: AssemblyTitle("MoreMusicMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MoreMusicMod
{
	[BepInPlugin("georgebjork.MoreMusicMod", "MoreMusicMod", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		private const string Guid = "georgebjork.MoreMusicMod";

		private const string Name = "MoreMusicMod";

		private const string Version = "1.0.2";

		private static Plugin _instance;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			_instance = this;
			ResourceLoaderService.GenerateFolders();
			Harmony val = new Harmony("georgebjork.MoreMusicMod");
			val.PatchAll(typeof(BoomboxPatch));
			val.PatchAll(typeof(StartUp));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin georgebjork.MoreMusicMod is loaded!");
		}

		internal static void LogDebug(string message)
		{
			_instance.Log(message, (LogLevel)32);
		}

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

		internal static void LogWarning(string message)
		{
			_instance.Log(message, (LogLevel)4);
		}

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

		internal static void LogError(Exception ex)
		{
			_instance.Log(ex.Message + "\n" + ex.StackTrace, (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);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MoreMusicMod";

		public const string PLUGIN_NAME = "MoreMusicMod";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace MoreMusicMod.Services
{
	public class AudioLoaderService : BaseService
	{
		private static readonly List<AudioClip> _clips = new List<AudioClip>();

		private static string[] _songs_at_directory;

		public static bool IsLoaded = false;

		public static bool UseDefaultSongs => !IsLoaded && _songs_at_directory.Length == 0;

		public static int ClipsLength => _clips.Count;

		public static event Action AllSongsLoaded;

		public static void LoadAllSongs()
		{
			GetFilesAtDirectory();
			Plugin.LogInfo("Attempting to load songs...");
			try
			{
				List<IEnumerator> list = new List<IEnumerator>();
				string[] songs_at_directory = _songs_at_directory;
				foreach (string filePath in songs_at_directory)
				{
					list.Add(LoadAudioClip(filePath));
				}
				BaseService.HandleCoroutineList(list, OnAllSongsLoaded);
			}
			catch (Exception arg)
			{
				Plugin.LogError($"There was an error loading audio tracks. Exception: {arg}");
			}
		}

		private static void GetFilesAtDirectory()
		{
			if (!IsLoaded)
			{
				_songs_at_directory = Directory.GetFiles(BaseService._music_directory);
				if (_songs_at_directory.Length == 0)
				{
					Plugin.LogWarning("No songs where found at " + BaseService._music_directory);
				}
				else
				{
					Plugin.LogInfo("Songs found!");
				}
			}
		}

		private static IEnumerator LoadAudioClip(string filePath)
		{
			Plugin.LogInfo("Loading track: " + Path.GetFileName(filePath));
			AudioType audioType = AudioHelper.GetAudioType(filePath);
			if ((int)audioType == 0)
			{
				Plugin.LogError("Failed to load AudioClip from " + filePath + ". Unsupported file extension. Supported types are: MPEG, WAV, and OGGVORBIS ");
				yield break;
			}
			AudioClip clip = StreamAudioClipFromDisk(filePath, audioType);
			if (clip != null)
			{
				((Object)clip).name = Path.GetFileName(filePath);
				_clips.Add(clip);
				Plugin.LogInfo("Clip added.");
			}
		}

		private static AudioClip StreamAudioClipFromDisk(string filePath, AudioType audioType)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(filePath, audioType);
			try
			{
				((DownloadHandlerAudioClip)audioClip.downloadHandler).streamAudio = true;
				audioClip.timeout = 10;
				audioClip.SendWebRequest();
				while (!audioClip.isDone)
				{
					if (audioClip.error == null || audioClip.timeout <= 10)
					{
						continue;
					}
					Plugin.LogError("Error loading clip: " + Path.GetFileName(filePath) + ": " + audioClip.error);
					return null;
				}
				return DownloadHandlerAudioClip.GetContent(audioClip);
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
		}

		public static void AddClips(BoomboxItem __instance)
		{
			Plugin.LogInfo("Adding clips!");
			__instance.musicAudios = (UseDefaultSongs ? __instance.musicAudios.Concat(_clips).ToArray() : _clips.ToArray());
			Plugin.LogInfo($"{_clips.Count}/{_songs_at_directory.Length} where loaded!!");
		}

		private static void OnAllSongsLoaded()
		{
			AudioLoaderService.AllSongsLoaded?.Invoke();
			AudioLoaderService.AllSongsLoaded = null;
			IsLoaded = true;
		}
	}
	public class BaseService : MonoBehaviour
	{
		private static BaseService _instance;

		protected static readonly string _music_directory = Path.Combine(Paths.BepInExRootPath, Settings.PLUGINS_DIRECTORY, Settings.SONGS_FOLDER);

		protected static readonly string _plugins_directory = Path.Combine(Paths.BepInExRootPath, Settings.PLUGINS_DIRECTORY);

		private static readonly List<Coroutine> _active_coroutines = new List<Coroutine>();

		protected static Coroutine StartCoroutine(IEnumerator routine)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_instance != (Object)null)
			{
				return ((MonoBehaviour)_instance).StartCoroutine(routine);
			}
			_instance = new GameObject("Shared Coroutine Starter").AddComponent<BaseService>();
			Object.DontDestroyOnLoad((Object)(object)_instance);
			return ((MonoBehaviour)_instance).StartCoroutine(routine);
		}

		protected static void HandleCoroutineList(List<IEnumerator> coroutines, Action onComplete)
		{
			StartCoroutine(RunCoroutineList(coroutines, onComplete));
		}

		private static IEnumerator RunCoroutineList(List<IEnumerator> coroutineList, Action onComplete)
		{
			foreach (IEnumerator routine in coroutineList)
			{
				Coroutine rv = StartCoroutine(routine);
				_active_coroutines.Add(rv);
			}
			foreach (Coroutine active_coroutine in _active_coroutines)
			{
				yield return active_coroutine;
			}
			_active_coroutines.Clear();
			Plugin.LogInfo($"ALL DONE!! {_active_coroutines.Count}");
			onComplete?.Invoke();
		}
	}
	public class ResourceLoaderService : BaseService
	{
		public static void GenerateFolders()
		{
			try
			{
				if (Directory.Exists(BaseService._music_directory))
				{
					Plugin.LogInfo("Directory already exists at: " + BaseService._music_directory);
					return;
				}
				Directory.CreateDirectory(BaseService._music_directory);
				Plugin.LogInfo("Directory created at: " + BaseService._music_directory);
				CheckFoldersForMusicDirectory();
			}
			catch (Exception ex)
			{
				Plugin.LogError(ex);
				Plugin.LogError("Something went wrong. Unable to create directory at " + BaseService._music_directory);
			}
		}

		private static void CheckFoldersForMusicDirectory()
		{
			try
			{
				List<string> list = Directory.GetDirectories(BaseService._plugins_directory).ToList();
				list.Remove(BaseService._music_directory);
				foreach (string item in list)
				{
					if (CheckFolder(item))
					{
						MoveFilesFromFolderToMusicDirectory(Path.Combine(item, Settings.SONGS_FOLDER));
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogError("An error occurred: " + ex.Message);
			}
		}

		private static bool CheckFolder(string folder)
		{
			return Directory.Exists(Path.Combine(folder, Settings.SONGS_FOLDER));
		}

		private static void MoveFilesFromFolderToMusicDirectory(string folder)
		{
			string[] files = Directory.GetFiles(folder);
			Plugin.LogInfo($"Moving from {folder}, {files.Length} files found.");
			string[] array = files;
			foreach (string text in array)
			{
				string fileName = Path.GetFileName(text);
				string text2 = Path.Combine(BaseService._music_directory, fileName);
				File.Copy(text, text2);
				Plugin.LogInfo("Moved " + text + " to " + text2);
			}
		}
	}
}
namespace MoreMusicMod.Patches
{
	[HarmonyPatch(typeof(BoomboxItem))]
	internal static class BoomboxPatch
	{
		private static int CurrentIndex;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Start(BoomboxItem __instance)
		{
			Plugin.LogInfo($"Is our music loaded: ${AudioLoaderService.IsLoaded}");
			if (AudioLoaderService.IsLoaded)
			{
				AudioLoaderService.AddClips(__instance);
				return;
			}
			AudioLoaderService.AllSongsLoaded += delegate
			{
				AudioLoaderService.AddClips(__instance);
			};
		}

		[HarmonyPatch("StartMusic")]
		[HarmonyPrefix]
		private static bool StartMusicPrefix(BoomboxItem __instance, ref bool startMusic, bool pitchDown)
		{
			if (startMusic)
			{
				__instance.boomboxAudio.clip = __instance.musicAudios[CurrentIndex];
				__instance.boomboxAudio.pitch = 1f;
				__instance.boomboxAudio.Play();
				CurrentIndex = (CurrentIndex + 1) % __instance.musicAudios.Length;
				((GrabbableObject)__instance).isBeingUsed = startMusic;
				__instance.isPlayingMusic = startMusic;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartUp
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		private static void Prefix()
		{
			AudioLoaderService.LoadAllSongs();
			Plugin.LogInfo($"Is using default songs: {AudioLoaderService.UseDefaultSongs}");
		}
	}
}
namespace MoreMusicMod.Helpers
{
	public class AudioHelper
	{
		public static AudioType GetAudioType(string path)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(path).ToLower();
			switch (text)
			{
			case ".wav":
				return (AudioType)20;
			case ".ogg":
				return (AudioType)14;
			case ".mp3":
				return (AudioType)13;
			default:
				Plugin.LogError("Unsupported extension type: " + text);
				return (AudioType)0;
			}
		}
	}
}
namespace MoreMusicMod.Configuration
{
	public static class Settings
	{
		public static string PLUGINS_DIRECTORY = "plugins";

		public static string SONGS_FOLDER = "MoreMusic/Music";
	}
}