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";
}
}