using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CustomBoomboxTracks.Configuration;
using CustomBoomboxTracks.Managers;
using CustomBoomboxTracks.Utilities;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomBoomboxTracks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+e175c21c6157b95c1fd6b2fa48ef949a84089d0e")]
[assembly: AssemblyProduct("CustomBoomboxTracks")]
[assembly: AssemblyTitle("CustomBoomboxTracks")]
[assembly: AssemblyVersion("1.0.3.0")]
namespace CustomBoomboxTracks
{
[BepInPlugin("inspiired.lethalcompany.boomboxmod", "BetterBoomboxMusic", "1.0.3")]
public class BoomboxPlugin : BaseUnityPlugin
{
private const string GUID = "inspiired.lethalcompany.boomboxmod";
private const string NAME = "BetterBoomboxMusic";
private const string VERSION = "1.0.3";
private static BoomboxPlugin Instance;
private static bool downloadsStarted;
private void Awake()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
LogInfo("Loading...");
DownloadManager.GenerateFolders();
Config.Init();
SceneManager.sceneLoaded += OnSceneLoaded;
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name == "MainMenu" && !downloadsStarted)
{
StartDownloads();
}
new Harmony("inspiired.lethalcompany.boomboxmod").PatchAll();
LogInfo("Loading Complete!");
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (((Scene)(ref scene)).name == "MainMenu" && !downloadsStarted)
{
StartDownloads();
}
}
private void StartDownloads()
{
if (!downloadsStarted)
{
downloadsStarted = true;
LogInfo("MainMenu scene detected. Starting downloads...");
List<string> songDownloadLinks = Config.SongDownloadLinks;
if (songDownloadLinks.Count == 0)
{
LogWarning("No download links found in the configuration.");
}
else
{
DownloadManager.DownloadSongsFromConfig(songDownloadLinks);
}
}
}
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);
}
}
}
namespace CustomBoomboxTracks.Utilities
{
public 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 CustomBoomboxTracks.Patches
{
[HarmonyPatch(typeof(BoomboxItem), "PocketItem")]
internal class BoomboxItem_PocketItem
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> list = instructions.ToList();
bool flag = false;
for (int i = 0; i < list.Count; i++)
{
if (!flag)
{
if (list[i].opcode == OpCodes.Call)
{
flag = true;
}
continue;
}
if (list[i].opcode == OpCodes.Ret)
{
break;
}
list[i].opcode = OpCodes.Nop;
}
return list;
}
}
[HarmonyPatch(typeof(BoomboxItem), "Start")]
internal class BoomboxItem_Start
{
private static void Postfix(BoomboxItem __instance)
{
if (AudioManager.FinishedLoading)
{
AudioManager.ApplyClips(__instance);
return;
}
AudioManager.OnAllSongsLoaded += delegate
{
AudioManager.ApplyClips(__instance);
};
}
}
[HarmonyPatch(typeof(BoomboxItem), "StartMusic")]
internal class BoomboxItem_StartMusic
{
private static void Postfix(BoomboxItem __instance, bool startMusic)
{
if (startMusic)
{
BoomboxPlugin.LogInfo("Playing " + ((Object)__instance.boomboxAudio.clip).name);
}
}
}
[HarmonyPatch(typeof(StartOfRound), "Awake")]
internal class StartOfRound_Awake
{
private static void Prefix()
{
AudioManager.Load();
}
}
}
namespace CustomBoomboxTracks.Managers
{
public static class DownloadManager
{
private static readonly string directory = Path.Combine(Paths.BepInExRootPath, "Custom Songs", "Boombox Music");
private static int pendingDownloads = 0;
private static Action onDownloadsComplete;
private static readonly string trackFilePath = Path.Combine(Paths.BepInExRootPath, "Custom Songs", "downloadedFiles.txt");
public static void GenerateFolders()
{
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
BoomboxPlugin.LogInfo("Created directory at " + directory);
}
}
public static void DownloadSongsFromConfig(List<string> downloadLinks, Action onComplete = null)
{
GenerateFolders();
if (downloadLinks == null || downloadLinks.Count == 0)
{
BoomboxPlugin.LogWarning("No download links provided in the config!");
onComplete?.Invoke();
return;
}
pendingDownloads = downloadLinks.Count;
onDownloadsComplete = onComplete;
BoomboxPlugin.LogInfo($"Starting downloads: {pendingDownloads} files to download.");
foreach (string downloadLink in downloadLinks)
{
SharedCoroutineStarter.StartCoroutine(HandleDownload(downloadLink));
}
}
private static IEnumerator HandleDownload(string url)
{
string text = null;
if (IsGoogleDriveLink(url))
{
text = ExtractGoogleDriveFileId(url);
}
if (string.IsNullOrEmpty(text))
{
BoomboxPlugin.LogError("Failed to extract fileId from the URL: " + url);
yield break;
}
string url2 = "https://drive.google.com/uc?export=download&id=" + text;
if (HasFileBeenDownloadedBefore(text))
{
BoomboxPlugin.LogInfo("Skipping download, file with ID " + text + " has been previously downloaded.");
pendingDownloads--;
BoomboxPlugin.LogInfo($"Pending downloads: {pendingDownloads} remaining.");
if (pendingDownloads == 0 && onDownloadsComplete != null)
{
BoomboxPlugin.LogInfo("All downloads complete.");
onDownloadsComplete();
onDownloadsComplete = null;
}
}
else
{
BoomboxPlugin.LogInfo($"Pending downloads: {pendingDownloads}");
yield return GetFileMetadataBeforeDownload(url2);
}
}
private static bool HasFileBeenDownloadedBefore(string fileId)
{
BoomboxPlugin.LogInfo("Checking if file " + fileId + " has been downloaded before.");
if (!File.Exists(trackFilePath))
{
return false;
}
string[] array = File.ReadAllLines(trackFilePath);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(',');
if (array2.Length == 1 && array2[0] == fileId)
{
return true;
}
}
BoomboxPlugin.LogInfo("File " + fileId + " has not been downloaded before.");
return false;
}
private static IEnumerator GetFileMetadataBeforeDownload(string url)
{
string fileId = (IsGoogleDriveLink(url) ? ExtractGoogleDriveFileId(url) : null);
string fileName2 = Path.GetFileName(url);
UnityWebRequest request = UnityWebRequest.Head(url);
try
{
yield return request.SendWebRequest();
if ((int)request.result == 1)
{
fileName2 = GetSanitizedFileName(request, fileName2);
BoomboxPlugin.LogInfo("Remote file for " + fileName2 + " (Google Drive ID: " + fileId + ")");
yield return IsGoogleDriveLink(url) ? DownloadGoogleDriveFile(url, fileName2, fileId) : DownloadFile(url, fileName2);
}
else
{
BoomboxPlugin.LogError("Failed to retrieve metadata for " + url + ": " + request.error);
}
}
finally
{
((IDisposable)request)?.Dispose();
}
}
private static string GetSanitizedFileName(UnityWebRequest request, string fileName)
{
string responseHeader = request.GetResponseHeader("Content-Disposition");
if (!string.IsNullOrEmpty(responseHeader) && responseHeader.Contains("filename="))
{
int startIndex = responseHeader.IndexOf("filename=") + "filename=".Length;
fileName = responseHeader.Substring(startIndex).Trim('"');
}
if (string.IsNullOrEmpty(fileName) || fileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
{
fileName = $"{Guid.NewGuid()}.unknown";
}
return string.Join("_", fileName.Split(Path.GetInvalidFileNameChars()));
}
private static bool IsGoogleDriveLink(string url)
{
try
{
Uri uri = new Uri(url);
return uri.Host.Equals("drive.google.com", StringComparison.OrdinalIgnoreCase) || uri.Host.Equals("docs.google.com", StringComparison.OrdinalIgnoreCase);
}
catch
{
return false;
}
}
private static string ExtractGoogleDriveFileId(string url)
{
string pattern = "[?&]id=([a-zA-Z0-9_-]+)";
string pattern2 = "drive\\.google\\.com\\/file\\/d\\/([a-zA-Z0-9_-]+)";
Match match = Regex.Match(url, pattern);
if (match.Success)
{
return match.Groups[1].Value;
}
Match match2 = Regex.Match(url, pattern2);
if (match2.Success)
{
return match2.Groups[1].Value;
}
return null;
}
private static IEnumerator DownloadGoogleDriveFile(string url, string fileName, string fileId)
{
BoomboxPlugin.LogInfo("Processing Google Drive link: " + url);
UnityWebRequest request = UnityWebRequest.Get(url);
try
{
request.redirectLimit = 0;
yield return request.SendWebRequest();
if ((int)request.result == 1)
{
BoomboxPlugin.LogInfo("No redirect detected. Proceeding with normal download.");
yield return DownloadFile(url, fileName, fileId);
}
else if (request.responseCode == 302 || request.responseCode == 303)
{
string redirectUrl = request.GetResponseHeader("Location");
BoomboxPlugin.LogInfo("Redirect detected. Redirecting to: " + redirectUrl);
if (redirectUrl.Contains("drive.usercontent.google.com") && redirectUrl.Contains("download"))
{
UnityWebRequest virusScanRequest = UnityWebRequest.Get(redirectUrl);
try
{
yield return virusScanRequest.SendWebRequest();
if ((int)virusScanRequest.result == 1)
{
if (virusScanRequest.downloadHandler.text.Contains("<p class=\"uc-warning-caption\">Google Drive can't scan this file for viruses.</p>"))
{
BoomboxPlugin.LogInfo("Virus scan warning page detected.");
yield return HandleVirusScanRedirect(redirectUrl, fileName, fileId);
}
else
{
BoomboxPlugin.LogInfo("No virus scan warning detected. Proceeding with direct download.");
yield return DownloadFile(url, fileName, fileId);
}
}
else
{
BoomboxPlugin.LogError("Failed to check virus scan page: " + virusScanRequest.error);
yield return DownloadFile(url, fileName, fileId);
}
}
finally
{
((IDisposable)virusScanRequest)?.Dispose();
}
}
else
{
BoomboxPlugin.LogInfo("Redirect is not a virus scan page. Proceeding with direct download.");
yield return DownloadFile(url, fileName, fileId);
}
}
else
{
BoomboxPlugin.LogError("Failed to download file " + url + ": " + request.error);
}
}
finally
{
((IDisposable)request)?.Dispose();
}
}
private static IEnumerator HandleVirusScanRedirect(string url, string fileName, string fileId)
{
UnityWebRequest redirectRequest = UnityWebRequest.Get(url);
try
{
yield return redirectRequest.SendWebRequest();
if ((int)redirectRequest.result == 1)
{
string text = redirectRequest.downloadHandler.text;
string text2 = ExtractFileNameFromHtml(text);
if (!string.IsNullOrEmpty(text2))
{
fileName = text2;
}
string text3 = ExtractFormField(text, "name=\"id\" value=\"");
string text4 = ExtractFormField(text, "name=\"export\" value=\"");
string text5 = ExtractFormField(text, "name=\"confirm\" value=\"");
string text6 = ExtractFormField(text, "name=\"uuid\" value=\"");
if (string.IsNullOrEmpty(fileId) && !string.IsNullOrEmpty(text3))
{
fileId = text3;
}
if (string.IsNullOrEmpty(text3) || string.IsNullOrEmpty(text4) || string.IsNullOrEmpty(text5) || string.IsNullOrEmpty(text6) || string.IsNullOrEmpty(fileId))
{
BoomboxPlugin.LogWarning("Required parameters missing. Retrying with original URL...");
yield return DownloadFile(url, fileName, fileId);
yield break;
}
string text7 = "https://drive.usercontent.google.com/download?id=" + text3 + "&export=" + text4 + "&confirm=" + text5 + "&uuid=" + text6;
BoomboxPlugin.LogInfo("Constructed final URL: " + text7);
yield return DownloadFile(text7, fileName, fileId);
}
else
{
BoomboxPlugin.LogError("Failed to retrieve virus scan warning page: " + redirectRequest.error);
}
}
finally
{
((IDisposable)redirectRequest)?.Dispose();
}
}
private static string ExtractFileNameFromHtml(string html)
{
string pattern = "<span class=\"uc-name-size\"><a href=\"/open\\?id=[^\"]+\">([^<]+)</a>";
Match match = Regex.Match(html, pattern);
if (!match.Success)
{
return null;
}
return match.Groups[1].Value;
}
private static string ExtractFormField(string html, string fieldName)
{
int num = html.IndexOf(fieldName);
if (num == -1)
{
return null;
}
num += fieldName.Length;
int num2 = html.IndexOf("\"", num);
if (num2 == -1)
{
return null;
}
return html.Substring(num, num2 - num);
}
private static IEnumerator DownloadFile(string url, string fileName, string fileId = null)
{
string savePath = Path.Combine(directory, fileName);
if (!Path.GetFullPath(savePath).StartsWith(Path.GetFullPath(directory), StringComparison.OrdinalIgnoreCase))
{
throw new UnauthorizedAccessException("Invalid ZIP entry: " + fileName);
}
UnityWebRequest request = UnityWebRequest.Get(url);
try
{
request.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
request.timeout = 300;
BoomboxPlugin.LogInfo("Downloading " + url + "...");
yield return request.SendWebRequest();
float lastReportedProgress = 0f;
while (!request.isDone)
{
if (Mathf.Abs(request.downloadProgress - lastReportedProgress) >= 0.05f)
{
lastReportedProgress = request.downloadProgress;
BoomboxPlugin.LogInfo($"Download progress: {request.downloadProgress * 100f:0.00}%");
}
yield return null;
}
if ((int)request.result != 1)
{
BoomboxPlugin.LogError("Failed to download " + url + ": " + request.error);
yield break;
}
byte[] data = request.downloadHandler.data;
if (data == null || data.Length == 0)
{
BoomboxPlugin.LogError("Downloaded data is empty for " + url);
yield break;
}
File.WriteAllBytes(savePath, data);
BoomboxPlugin.LogInfo("Downloaded and saved " + fileName + " to " + savePath);
UpdateFileMetadata(fileId);
new FileInfo(savePath);
if (Path.GetExtension(fileName).ToLower() == ".zip")
{
ExtractZipAndSaveMetadata(savePath, directory);
File.Delete(savePath);
BoomboxPlugin.LogInfo("ZIP file deleted: " + savePath);
}
}
finally
{
((IDisposable)request)?.Dispose();
}
}
private static void UpdateFileMetadata(string fileId)
{
List<string> list = (File.Exists(trackFilePath) ? new List<string>(File.ReadAllLines(trackFilePath)) : new List<string>());
bool flag = false;
for (int i = 0; i < list.Count; i++)
{
string text = list[i];
if (text.Split(',')[0] == fileId)
{
flag = true;
list[i] = text + "," + fileId;
break;
}
}
if (!flag)
{
list.Add(fileId);
}
File.WriteAllLines(trackFilePath, list);
BoomboxPlugin.LogInfo("Metadata updated: " + fileId);
}
private static void ExtractZipAndSaveMetadata(string zipPath, string extractTo)
{
try
{
using (ZipArchive zipArchive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in zipArchive.Entries)
{
if (!string.IsNullOrEmpty(entry.Name))
{
string fileName = Path.GetFileName(entry.FullName);
string fullPath = Path.GetFullPath(Path.Combine(extractTo, fileName));
if (!fullPath.StartsWith(Path.GetFullPath(extractTo), StringComparison.OrdinalIgnoreCase))
{
throw new UnauthorizedAccessException("Invalid ZIP entry: " + entry.FullName);
}
string uniqueFilePath = GetUniqueFilePath(fullPath);
entry.ExtractToFile(uniqueFilePath, overwrite: false);
BoomboxPlugin.LogInfo("Extracted file: " + uniqueFilePath);
}
}
}
BoomboxPlugin.LogInfo("Extraction complete for " + zipPath);
}
catch (Exception ex)
{
BoomboxPlugin.LogError("Error extracting ZIP: " + ex.Message);
}
}
private static string GetUniqueFilePath(string filePath)
{
string directoryName = Path.GetDirectoryName(filePath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
string extension = Path.GetExtension(filePath);
int num = 1;
string text = filePath;
while (File.Exists(text))
{
text = Path.Combine(directoryName, $"{fileNameWithoutExtension} ({num}){extension}");
num++;
}
return text;
}
}
internal static class AudioManager
{
private static readonly string directory = Path.Combine(Paths.BepInExRootPath, "Custom Songs", "Boombox Music");
private static string[] allSongPaths;
private static readonly List<AudioClip> audioClips = new List<AudioClip>();
private static List<AudioClip> clips = audioClips;
private static bool finishedLoading = false;
private static bool firstRun = true;
public static bool FinishedLoading => finishedLoading;
public static bool HasNoSongs => allSongPaths.Length == 0;
public static event Action OnAllSongsLoaded;
public static void Load()
{
if (!firstRun)
{
return;
}
firstRun = false;
BoomboxPlugin.LogInfo("Starting to load audio clips...");
if (!Directory.Exists(directory))
{
BoomboxPlugin.LogError("Directory " + directory + " does not exist.");
return;
}
allSongPaths = Directory.GetFiles(directory);
if (allSongPaths.Length == 0)
{
BoomboxPlugin.LogWarning("No pre-existing songs found!");
}
else
{
CheckAndLoadAudioClips();
}
}
private static void CheckAndLoadAudioClips()
{
if (!Directory.Exists(directory))
{
BoomboxPlugin.LogError("Directory " + directory + " does not exist.");
return;
}
allSongPaths = Directory.GetFiles(directory);
if (allSongPaths.Length == 0)
{
BoomboxPlugin.LogWarning("No pre-existing songs found!");
return;
}
BoomboxPlugin.LogInfo("Preparing to load AudioClips...");
List<Coroutine> list = new List<Coroutine>();
string[] array = allSongPaths;
for (int i = 0; i < array.Length; i++)
{
Coroutine item = SharedCoroutineStarter.StartCoroutine(LoadAudioClip(array[i]));
list.Add(item);
}
SharedCoroutineStarter.StartCoroutine(WaitForAllClips(list));
}
private static IEnumerator LoadAudioClip(string filePath)
{
BoomboxPlugin.LogInfo("Loading " + filePath + "!");
if ((int)GetAudioType(filePath) == 0)
{
BoomboxPlugin.LogError("Failed to load AudioClip from " + filePath + "\nUnsupported file extension!");
yield break;
}
UnityWebRequest loader = UnityWebRequestMultimedia.GetAudioClip(filePath, GetAudioType(filePath));
if (Config.StreamFromDisk)
{
DownloadHandler downloadHandler = loader.downloadHandler;
((DownloadHandlerAudioClip)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null)).streamAudio = true;
}
loader.SendWebRequest();
while (!loader.isDone)
{
yield return null;
}
if (loader.error != null)
{
BoomboxPlugin.LogError("Error loading clip from path: " + filePath + "\n" + loader.error);
yield break;
}
AudioClip content = DownloadHandlerAudioClip.GetContent(loader);
if (Object.op_Implicit((Object)(object)content) && (int)content.loadState == 2)
{
BoomboxPlugin.LogInfo("Successfully loaded: " + filePath);
((Object)content).name = Path.GetFileName(filePath);
clips.Add(content);
}
else
{
BoomboxPlugin.LogError("Failed to load clip at: " + filePath);
}
}
private static IEnumerator WaitForAllClips(List<Coroutine> coroutines)
{
foreach (Coroutine coroutine in coroutines)
{
yield return coroutine;
}
BoomboxPlugin.LogInfo("Finished loading all clips!");
clips.Sort((AudioClip first, AudioClip second) => ((Object)first).name.CompareTo(((Object)second).name));
foreach (AudioClip clip in clips)
{
BoomboxPlugin.LogInfo("Clip loaded: " + ((Object)clip).name);
}
finishedLoading = true;
AudioManager.OnAllSongsLoaded?.Invoke();
AudioManager.OnAllSongsLoaded = null;
}
public static void ApplyClips(BoomboxItem __instance)
{
BoomboxPlugin.LogInfo("Applying clips!");
if (Config.UseDefaultSongs)
{
__instance.musicAudios = __instance.musicAudios.Concat(clips).ToArray();
}
else
{
__instance.musicAudios = clips.ToArray();
}
BoomboxPlugin.LogInfo($"Total Clip Count: {__instance.musicAudios.Length}");
}
private static AudioType GetAudioType(string path)
{
string text = Path.GetExtension(path).ToLower();
switch (text)
{
case ".wav":
return (AudioType)20;
case ".ogg":
return (AudioType)14;
case ".mp3":
return (AudioType)13;
default:
BoomboxPlugin.LogError("Unsupported extension type: " + text);
return (AudioType)0;
}
}
}
}
namespace CustomBoomboxTracks.Configuration
{
internal static class Config
{
private const string CONFIG_FILE_NAME = "boombox.cfg";
private static ConfigFile _config;
private static ConfigEntry<bool> _useDefaultSongs;
private static ConfigEntry<bool> _streamAudioFromDisk;
private static ConfigEntry<string> _songDownloadUrls;
public static bool UseDefaultSongs
{
get
{
if (!_useDefaultSongs.Value)
{
return AudioManager.HasNoSongs;
}
return true;
}
}
public static bool StreamFromDisk => _streamAudioFromDisk.Value;
public static List<string> SongDownloadLinks
{
get
{
if (string.IsNullOrWhiteSpace(_songDownloadUrls.Value))
{
return new List<string>();
}
return (from url in _songDownloadUrls.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
select url.Trim()).ToList();
}
}
public static void Init()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
BoomboxPlugin.LogInfo("Initializing config...");
_config = new ConfigFile(Path.Combine(Paths.ConfigPath, "boombox.cfg"), true);
_useDefaultSongs = _config.Bind<bool>("General", "Use Default Songs", false, "Include the default songs in the rotation.");
_streamAudioFromDisk = _config.Bind<bool>("General", "Stream Audio From Disk", false, "Requires less memory and takes less time to load, but prevents playing the same song twice at once.");
_songDownloadUrls = _config.Bind<string>("Downloads", "Song Download URLs", "", "Comma-separated list of URLs for song downloads. Supports direct Google Drive links (including .zip files). DOES NOT support Google Drive folder links. Make sure URL share settings are set to public.");
BoomboxPlugin.LogInfo("Config initialized!");
}
private static void PrintConfig()
{
BoomboxPlugin.LogInfo($"Use Default Songs: {_useDefaultSongs.Value}");
BoomboxPlugin.LogInfo($"Stream From Disk: {_streamAudioFromDisk.Value}");
BoomboxPlugin.LogInfo("Song Download URLs: " + _songDownloadUrls.Value);
}
}
}