Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of YPlayBoombox v2.6.0
plugins\YPlay.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Networking; using UnityEngine.SceneManagement; using YPlay.NetcodePatcher; using YPlay.controller; using YPlay.cruiser; using YPlay.other; using YPlayUtil; using YPlayUtil.Metadata; using YPlayUtil.Options; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("YPlay")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("YPlay")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a9e02c48-30aa-4cf0-bbce-b71de7f55747")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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 YPlay { internal class AudioLoader : MonoBehaviour { [CompilerGenerated] private sealed class <GetAudioClip>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public bool resync; public Controller controller; public int requestId; private string <filenameId>5__2; private bool <success>5__3; private AudioClip <audioClip>5__4; private UnityWebRequest <unityWebRequest>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAudioClip>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <filenameId>5__2 = null; <audioClip>5__4 = null; <unityWebRequest>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Invalid comparison between Unknown and I4 //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Invalid comparison between Unknown and I4 try { bool flag; bool flag2; switch (<>1__state) { default: return false; case 0: <>1__state = -1; <filenameId>5__2 = Path.GetFileNameWithoutExtension(path); flag = false; <success>5__3 = false; if (FilenameIdAudioClips.ContainsKey(<filenameId>5__2)) { <audioClip>5__4 = FilenameIdAudioClips[<filenameId>5__2]; if (AudioClipLoadedInMemory(<audioClip>5__4)) { <>2__current = null; <>1__state = 1; return true; } FilenameIdAudioClips.Remove(<filenameId>5__2); goto IL_00bf; } goto IL_00c6; case 1: <>1__state = -1; SetAudio(<filenameId>5__2, <audioClip>5__4); flag = true; <success>5__3 = true; goto IL_00bf; case 2: { <>1__state = -3; if ((int)<unityWebRequest>5__5.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(<unityWebRequest>5__5); if (AudioClipLoadedInMemory(content)) { ((Object)content).name = (AudioDownloader.AudioIdTitles.ContainsKey(<filenameId>5__2) ? AudioDownloader.AudioIdTitles[<filenameId>5__2] : null); SetAudio(<filenameId>5__2, content); <success>5__3 = true; } } <>m__Finally1(); <unityWebRequest>5__5 = null; break; } IL_00c6: flag2 = AudioDownloader.IsFilenameIdDownloaded(<filenameId>5__2); if (!flag && flag2) { if (FilenameIdsDownloaded.Contains(<filenameId>5__2)) { FilenameIdsDownloaded.Remove(<filenameId>5__2); } FilenameIdsDownloaded.Insert(0, <filenameId>5__2); AudioType audioType = AudioDownloader.AudioType; <unityWebRequest>5__5 = UnityWebRequestMultimedia.GetAudioClip(Path.Combine(YPlay.GameDirectory, path), audioType); <>1__state = -3; ((DownloadHandlerAudioClip)<unityWebRequest>5__5.downloadHandler).streamAudio = (int)audioType == 13; <>2__current = <unityWebRequest>5__5.SendWebRequest(); <>1__state = 2; return true; } break; IL_00bf: <audioClip>5__4 = null; goto IL_00c6; } if (!<success>5__3) { string text = "Error " + (resync ? "resyncing" : "loading") + " request " + AudioDownloader.GetFilenameIdString(<filenameId>5__2); YPlay.LogWarning(text); Patch.AddChatMessage(text); } controller.SendLoadedServerDelegate(requestId, <success>5__3, resync); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<unityWebRequest>5__5 != null) { ((IDisposable)<unityWebRequest>5__5).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static readonly Dictionary<string, AudioClip> FilenameIdAudioClips = new Dictionary<string, AudioClip>(); internal static readonly List<string> FilenameIdsDownloaded = new List<string>(); private static AudioLoader Instance; internal void Start(IEnumerator routine) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance == (Object)null) { Instance = new GameObject(typeof(AudioLoader).Name).AddComponent<AudioLoader>(); Object.DontDestroyOnLoad((Object)(object)Instance); } ((MonoBehaviour)Instance).StartCoroutine(routine); } [IteratorStateMachine(typeof(<GetAudioClip>d__4))] internal IEnumerator GetAudioClip(Controller controller, int requestId, string path, bool resync) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetAudioClip>d__4(0) { controller = controller, requestId = requestId, path = path, resync = resync }; } internal static void UnloadAudioClips() { foreach (KeyValuePair<string, AudioClip> item in new Dictionary<string, AudioClip>(FilenameIdAudioClips)) { AudioClip value = item.Value; string key = item.Key; value.UnloadAudioData(); FilenameIdAudioClips.Remove(key); } } private static bool AudioClipLoadedInMemory(AudioClip audioClip) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)audioClip) && audioClip.LoadAudioData()) { return (int)audioClip.loadState == 2; } return false; } private static void SetAudio(string filenameId, AudioClip audioClip) { FilenameIdAudioClips[filenameId] = audioClip; Patch.AddChatMessage("Loaded " + AudioDownloader.GetFilenameIdString(filenameId)); } } internal class AudioDownloader { [CompilerGenerated] private Controller <controller>P; internal static bool CanChangeSync = Patch.IsHost; internal static HashSet<string> FilenameIdsResyncing = new HashSet<string>(); internal static readonly Dictionary<string, string> AudioIdTitles = new Dictionary<string, string>(); private static readonly Dictionary<string, int> AudioIdDurations = new Dictionary<string, int>(); internal int lastDownloadRequestId; internal string lastDownloadRequestFilenameId; private readonly AudioLoader audioLoader; private AudioAction audioAction; internal static AudioType AudioType = (AudioType)13; internal static readonly OptionSet OverrideOptions; public AudioDownloader(Controller controller) { <controller>P = controller; lastDownloadRequestId = -1; audioLoader = new AudioLoader(); base..ctor(); } internal async void DownloadTask(int requestId, string filenameId, string title, int duration, string url, float time, bool resync = false) { if (CanChangeSync) { CanChangeSync = false; } if (string.IsNullOrEmpty(filenameId?.Trim()) || string.IsNullOrEmpty(title?.Trim()) || string.IsNullOrEmpty(url?.Trim())) { Patch.AddChatMessage("Invalid " + (resync ? "resync" : "download") + " request"); return; } if (resync) { FilenameIdsResyncing.Add(filenameId); } lastDownloadRequestId = requestId; lastDownloadRequestFilenameId = filenameId; time = Mathf.Max(time, 0f); REQUEST_STATUS requestStatusError = REQUEST_STATUS.NONE; string error = null; AudioIdTitles[filenameId] = title; AudioIdDurations[filenameId] = duration; string filenameIdString = GetFilenameIdString(filenameId); await Task.Run(delegate { string outputFileLocationForId = GetOutputFileLocationForId(filenameId); CancelCurrentProcess(); if (IsFilenameLoaded(filenameId)) { requestStatusError = LoadFile(filenameId, outputFileLocationForId, requestId, resync); } else if (!YPlay.IsYPlayUtilValid()) { requestStatusError = REQUEST_STATUS.ERROR_UTIL_MISSING_DEPENDENCY; error = "Missing dependency, please try reinstalling YPlayBoombox"; } else if (YPlay.IsDownloadingTools()) { requestStatusError = REQUEST_STATUS.ERROR_UTIL_DOWNLOADING_TOOLS; error = "Downloading tools..."; } else if (!YPlay.IsToolsExistAndNonEmpty()) { requestStatusError = REQUEST_STATUS.ERROR_INVALID_TOOLS; error = "Invalid tools, please try /yp update"; } else { audioAction = new AudioAction(this, requestId, filenameId, outputFileLocationForId, url); requestStatusError = audioAction.Start(resync); switch (requestStatusError) { case REQUEST_STATUS.ERROR_CLIENT_DOWNLOAD: error = "Error downloading request " + filenameIdString; break; case REQUEST_STATUS.ERROR_CLIENT_DOWNLOAD_EXCEPTION: error = "Error downloading request (exception) " + filenameIdString; break; case REQUEST_STATUS.ERROR_CLIENT_LOAD: error = "Error loading request " + filenameIdString; break; case REQUEST_STATUS.ERROR_METADATA_AGE_RESTRICTED: error = "Error downloading request (no access - age restricted) " + filenameIdString; break; case REQUEST_STATUS.ERROR_METADATA_BOT: error = "Error downloading request (no access - bot) " + filenameIdString; break; case REQUEST_STATUS.ERROR_METADATA_SIGN_IN: error = "Error downloading request (no access) " + filenameIdString; break; case REQUEST_STATUS.ERROR_METADATA_VIDEO_UNAVAILABLE: error = "Error downloading request (video unavailable) " + filenameIdString; break; } } }); if (requestStatusError != 0) { <controller>P.SendLoadedServerDelegate(requestId, loaded: false, resync, requestStatusError); if (string.IsNullOrEmpty(error)) { error = "Error downloading request " + filenameIdString; } YPlay.LogError(error); Patch.AddChatMessage(error); } FilenameIdsResyncing.Remove(filenameId); } internal void CancelCurrentProcess() { if (audioAction != null && audioAction.actionState == ACTION_STATE.PROCESSING) { audioAction.KillProcess(); Patch.AddChatMessage("Previous process canceled " + GetFilenameIdString(audioAction.filenameId)); } } internal void KillRequestId(int requestId) { if (audioAction != null && audioAction.requestId == requestId) { CancelCurrentProcess(); } } internal async Task DownloadMetadata(RequestMetadata requestMetadata, string url, string filenameId, float time) { await Task.Run(delegate { REQUEST_STATUS rEQUEST_STATUS = REQUEST_STATUS.NONE; if (string.IsNullOrEmpty(url?.Trim()) || string.IsNullOrEmpty(filenameId?.Trim())) { rEQUEST_STATUS = REQUEST_STATUS.ERROR_METADATA; } else if (!YPlay.IsYPlayUtilValid()) { rEQUEST_STATUS = REQUEST_STATUS.ERROR_UTIL_MISSING_DEPENDENCY; } else if (YPlay.IsDownloadingTools()) { rEQUEST_STATUS = REQUEST_STATUS.ERROR_UTIL_DOWNLOADING_TOOLS; } else if (!YPlay.IsToolsExistAndNonEmpty()) { rEQUEST_STATUS = REQUEST_STATUS.ERROR_INVALID_TOOLS; } if (rEQUEST_STATUS != 0) { requestMetadata.requestStatus = rEQUEST_STATUS; } else { string text = (AudioIdTitles.ContainsKey(filenameId) ? AudioIdTitles[filenameId] : null); int num = (AudioIdDurations.ContainsKey(filenameId) ? AudioIdDurations[filenameId] : 0); if (!IsMetadataLoadedForFilenameId(filenameId)) { REQUEST_STATUS rEQUEST_STATUS2; (text, num, rEQUEST_STATUS2) = GetAudioTitleDuration(url); if (rEQUEST_STATUS2 != 0) { requestMetadata.requestStatus = rEQUEST_STATUS2; return; } if (string.IsNullOrEmpty(text?.Trim()) || num == 0) { requestMetadata.requestStatus = REQUEST_STATUS.ERROR_METADATA; return; } AudioIdTitles[filenameId] = text; AudioIdDurations[filenameId] = num; } int num2 = num / 60; if (num2 > 12) { requestMetadata.requestStatus = REQUEST_STATUS.ERROR_METADATA_MAX_DURATION; } else if (string.IsNullOrEmpty(text?.Trim()) || num == 0) { requestMetadata.requestStatus = REQUEST_STATUS.ERROR_METADATA; } else { requestMetadata.filenameId = filenameId; requestMetadata.url = url; requestMetadata.time = time; requestMetadata.title = text; requestMetadata.duration = num; if (requestMetadata.requestStatus != REQUEST_STATUS.REQUEST_CANCELED) { requestMetadata.requestStatus = REQUEST_STATUS.REQUEST_VALID; } } } }); } private (string title, int duration, REQUEST_STATUS requestStatus) GetAudioTitleDuration(string url) { YoutubeDL val = YPlay.NewYoutubeDl(); string text = ""; int num = 0; REQUEST_STATUS rEQUEST_STATUS = REQUEST_STATUS.NONE; try { OptionSet overrideOptions = OverrideOptions; RunResult<VideoData> result = val.RunVideoDataFetch(url, default(CancellationToken), true, false, overrideOptions).GetAwaiter().GetResult(); if (result != null) { VideoData data = result.Data; if (data != null) { text = data.Title; num = (int)data.Duration.GetValueOrDefault(); } if (string.IsNullOrEmpty(text) || num <= 0) { bool flag = false; string[] errorOutput = result.ErrorOutput; foreach (string text2 in errorOutput) { if (text2.StartsWith("ERROR:") && !text2.Contains("fragment 1 not found")) { flag = true; YPlay.LogError("[E-ERR][yt-dlp] " + text2); if (rEQUEST_STATUS == REQUEST_STATUS.NONE) { rEQUEST_STATUS = GetRequestStatusDownloadError(text2); } } } if (flag && rEQUEST_STATUS == REQUEST_STATUS.NONE) { Patch.AddChatMessage("Metadata error, please check the console"); rEQUEST_STATUS = REQUEST_STATUS.ERROR_METADATA; } } } } catch (Exception ex) { REQUEST_STATUS item; if (Patch.StringContainsLowerCase(ex.Message, "canceled")) { item = REQUEST_STATUS.REQUEST_CANCELED; } else { YPlay.LogError("[E-MEXC][yt-dlp] " + ex.Message); Patch.AddChatMessage("Metadata exception, please check the console"); item = REQUEST_STATUS.ERROR_METADATA_EXCEPTION; } return ("", 0, item); } if (string.IsNullOrEmpty(text?.Trim())) { text = GetFilenameIdFromUrl(url); } return (text, num, rEQUEST_STATUS); } internal REQUEST_STATUS LoadFile(string filenameId, string path, int requestId, bool resync) { if (IsFilenameLoaded(filenameId)) { audioLoader.Start(audioLoader.GetAudioClip(<controller>P, requestId, path, resync)); return REQUEST_STATUS.NONE; } return REQUEST_STATUS.ERROR_CLIENT_LOAD; } private bool IsFilenameLoaded(string filenameId) { if (!string.IsNullOrEmpty(filenameId?.Trim())) { if (!IsFilenameIdDownloaded(filenameId)) { return AudioLoader.FilenameIdAudioClips.ContainsKey(filenameId); } return true; } return false; } internal static bool IsFilenameIdDownloaded(string filenameId) { if (!string.IsNullOrEmpty(filenameId?.Trim())) { return IsFileValid(GetOutputFileLocationForId(filenameId)); } return false; } internal static bool IsFileValid(string path) { if (File.Exists(path)) { return new FileInfo(path).Length > 0; } return false; } internal static bool IsMetadataLoadedForFilenameId(string filenameId) { if (!string.IsNullOrEmpty(filenameId?.Trim()) && AudioIdTitles.ContainsKey(filenameId)) { return AudioIdDurations.ContainsKey(filenameId); } return false; } internal static string GetFilenameIdFromUrl(string url) { if (string.IsNullOrEmpty(url?.Trim())) { return null; } url = url.Replace("https://", "").Replace("http://", "").Replace("www.", ""); string text = null; int num = url.IndexOf("?v=", StringComparison.OrdinalIgnoreCase); int num2 = url.IndexOf("&v=", StringComparison.OrdinalIgnoreCase); int num3 = url.IndexOf("/shorts/", StringComparison.OrdinalIgnoreCase); int num4 = url.IndexOf("/", StringComparison.OrdinalIgnoreCase); if (num > -1) { text = url.Substring(num + "?v=".Length); } else if (num2 > -1) { text = url.Substring(num2 + "&v=".Length); } else if (num3 > -1) { text = url.Substring(num3 + "/shorts/".Length); } else if (num4 > -1) { text = url.Substring(num4 + "/".Length); } if (!string.IsNullOrEmpty(text?.Trim())) { int num5 = text.IndexOf("&", StringComparison.OrdinalIgnoreCase); if (num5 > -1) { text = text.Substring(0, num5); } int num6 = text.IndexOf("?", StringComparison.OrdinalIgnoreCase); if (num6 > -1) { text = text.Substring(0, num6); } } if (text == null) { return null; } string text2 = text.Trim(); if (text2.Length == 11) { return text2; } return null; } internal static void KillAllBoomboxDownloaderProcesses() { foreach (KeyValuePair<ulong, BoomboxController> item in new Dictionary<ulong, BoomboxController>(BoomboxController.BoomboxControllers)) { BoomboxController value = item.Value; value.audioDownloader.CancelCurrentProcess(); } } internal static string GetOutputFileLocationForId(string id) { return YPlay.AudioDirectory + "\\" + id + "." + GetFileExtension(); } internal static string GetFilenameIdString(string filenameId) { if (string.IsNullOrEmpty(filenameId?.Trim())) { return null; } return "[" + filenameId + "]"; } internal static string GetFileExtension() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)AudioType != 20) { return "mp3"; } return "wav"; } internal static REQUEST_STATUS GetRequestStatusDownloadError(string s) { if (s != null) { if (Patch.StringContainsLowerCase(s, "sign in")) { if (Patch.StringContainsLowerCase(s, "age")) { return REQUEST_STATUS.ERROR_METADATA_AGE_RESTRICTED; } if (Patch.StringContainsLowerCase(s, "bot")) { return REQUEST_STATUS.ERROR_METADATA_BOT; } return REQUEST_STATUS.ERROR_METADATA_SIGN_IN; } if (Patch.StringContainsLowerCase(s, "video unavailable")) { return REQUEST_STATUS.ERROR_METADATA_VIDEO_UNAVAILABLE; } } return REQUEST_STATUS.NONE; } static AudioDownloader() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown OptionSet val = new OptionSet(); val.FfmpegLocation = YPlay.FfmpegLocation; val.NoPlaylist = true; val.ForceIPv4 = true; val.NoRestrictFilenames = true; val.WindowsFilenames = true; val.PostprocessorArgs = MultiValue<string>.op_Implicit(new string[1] { "ffmpeg:-filter:a dynaudnorm" }); val.Cookies = "cookies.txt"; OverrideOptions = val; } } internal class AudioAction { internal ACTION_STATE actionState; private readonly AudioDownloader audioDownloader; internal int requestId; internal string filenameId; private readonly string outputFileLocation; private readonly string url; private readonly string tmpFile; private readonly string tmpFileWithExt; private readonly YoutubeDL youtubeDL; private readonly CancellationTokenSource cancellationTokenSource; internal AudioAction(AudioDownloader audioDownloader, int requestId, string filenameId, string outputFileLocation, string url) { this.audioDownloader = audioDownloader; this.requestId = requestId; this.filenameId = filenameId; this.outputFileLocation = outputFileLocation; this.url = url; tmpFile = YPlay.GetRandomTempFileLocation(); tmpFileWithExt = tmpFile + "." + AudioDownloader.GetFileExtension(); youtubeDL = YPlay.NewYoutubeDl(); youtubeDL.OutputFileTemplate = tmpFile; cancellationTokenSource = new CancellationTokenSource(); } internal REQUEST_STATUS Start(bool resync) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 if (resync) { Patch.AddChatMessage("Resyncing..."); } Patch.AddChatMessage("Downloading " + AudioDownloader.GetFilenameIdString(filenameId) + "..."); List<string> progressErrors = new List<string>(); REQUEST_STATUS rEQUEST_STATUS = REQUEST_STATUS.NONE; Progress<DownloadProgress> progress = new Progress<DownloadProgress>(delegate(DownloadProgress p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)p.State == 4 && p.Data != null && p.Data.Contains("ERROR") && !p.Data.Contains("Error opening output files") && !p.Data.Contains("Function not implemented") && !p.Data.Contains("The downloaded file is empty")) { progressErrors.Add(p.Data); } }); try { RunResult<string> result = youtubeDL.RunAudioDownload(url, (AudioConversionFormat)(((int)AudioDownloader.AudioType == 20) ? 7 : 3), cancellationTokenSource.Token, (IProgress<DownloadProgress>)progress, (IProgress<string>)null, AudioDownloader.OverrideOptions).GetAwaiter().GetResult(); } catch (Exception ex) { if (Patch.StringContainsLowerCase(ex.Message, "canceled")) { rEQUEST_STATUS = REQUEST_STATUS.ERROR_CLIENT_DOWNLOAD_CANCELED; } else { YPlay.LogError("[E-EXC][yt-dlp] " + ex.Message); Patch.AddChatMessage("Download exception, please check the console"); rEQUEST_STATUS = REQUEST_STATUS.ERROR_CLIENT_DOWNLOAD_EXCEPTION; } } bool flag = actionState == ACTION_STATE.PROCESSING && audioDownloader.lastDownloadRequestId == requestId; try { if (flag) { bool flag2 = AudioDownloader.IsFileValid(outputFileLocation); bool flag3 = AudioDownloader.IsFileValid(tmpFileWithExt); if (!flag2 && !flag3) { foreach (string item in progressErrors) { if (rEQUEST_STATUS == REQUEST_STATUS.NONE) { rEQUEST_STATUS = AudioDownloader.GetRequestStatusDownloadError(item); } YPlay.LogError("[E-PRO][yt-dlp] " + item); } if (rEQUEST_STATUS != 0) { KillProcess(); DeleteRequestFiles(); return rEQUEST_STATUS; } } if (!flag2) { if (!flag3) { throw new Exception("Failed to save temporary file"); } YPlay.CreateDirectory(YPlay.AudioDirectory); File.Move(tmpFileWithExt, outputFileLocation); } actionState = ACTION_STATE.FINISHED; return audioDownloader.LoadFile(filenameId, outputFileLocation, requestId, resync); } } catch (Exception ex2) { YPlay.LogError(ex2.Message); KillProcess(); return REQUEST_STATUS.ERROR_CLIENT_DOWNLOAD; } finally { DeleteRequestFiles(); } return REQUEST_STATUS.NONE; } internal void KillProcess() { if (actionState == ACTION_STATE.PROCESSING) { actionState = ACTION_STATE.KILLED; try { cancellationTokenSource?.Cancel(); } catch (Exception) { } } DeleteRequestFiles(); } private void DeleteRequestFiles() { Task.Delay(3000).ContinueWith(delegate { YPlay.DeleteFile(tmpFile); YPlay.DeleteFile(tmpFileWithExt); }); } } internal class BoomboxController : Controller { [CompilerGenerated] private sealed class <ColorPatternRainbow>d__32 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public BoomboxController <>4__this; private Color <color>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ColorPatternRainbow>d__32(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown int num = <>1__state; BoomboxController boomboxController = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; boomboxController.colorPattern = COLOR_PATTERN.RAINBOW; <color>5__2 = boomboxController.GetBoomboxBodyColor(); break; case 1: <>1__state = -1; break; } if (boomboxController.colorPattern == COLOR_PATTERN.RAINBOW && boomboxController.IsItemActive()) { <color>5__2 = ColorShift(<color>5__2, 0.2f * Time.deltaTime); boomboxController.ChangeBoomboxColor(<color>5__2.r, <color>5__2.g, <color>5__2.b); <>2__current = (object)new WaitForSeconds(0.05f); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ColorPatternRandomLoop>d__31 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public BoomboxController <>4__this; public ulong clientId; private bool <msg>5__2; private int <i>5__3; private bool <randomTextColorsSent>5__4; private string <colorPatternString>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ColorPatternRandomLoop>d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <colorPatternString>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; BoomboxController boomboxController = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; boomboxController.colorPattern = COLOR_PATTERN.RANDOM_LOOP; <msg>5__2 = true; <i>5__3 = 0; <randomTextColorsSent>5__4 = false; boomboxController.colorPatternRandomTextColors = new List<Color>(); string text = "RANDOM"; foreach (char c in text) { boomboxController.colorPatternRandomTextColors.Add(GetRandomBoomboxColor()); } <colorPatternString>5__5 = boomboxController.GetColorPatternString(boomboxController.colorPattern); break; } case 1: <>1__state = -1; break; } if (boomboxController.colorPattern == COLOR_PATTERN.RANDOM_LOOP && boomboxController.IsItemActive()) { if (!<randomTextColorsSent>5__4 && boomboxController.colorPatternRandomTextColors.Count > 0) { boomboxController.SyncBoomboxColor(boomboxController.colorPatternRandomTextColors[<i>5__3++], boomboxController.colorPattern, <colorPatternString>5__5, clientId, <msg>5__2); if (<i>5__3 >= boomboxController.colorPatternRandomTextColors.Count) { <randomTextColorsSent>5__4 = true; } } else { boomboxController.SyncBoomboxColor(GetRandomBoomboxColor(), boomboxController.colorPattern, <colorPatternString>5__5, clientId); } <colorPatternString>5__5 = null; <msg>5__2 = false; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static readonly Dictionary<ulong, BoomboxController> BoomboxControllers = new Dictionary<ulong, BoomboxController>(); internal BoomboxItem boomboxItem; private COLOR_PATTERN colorPattern; private IEnumerator colorPatternCoroutine; private const string colorPatternRandomText = "RANDOM"; private List<Color> colorPatternRandomTextColors = new List<Color>(); private readonly Dictionary<string, string> colorPatternRainbowDict = new Dictionary<string, string> { { "R", "red" }, { "A", "orange" }, { "I", "yellow" }, { "N", "green" }, { "B", "lightblue" }, { "O", "mediumpurple" }, { "W", "violet" } }; internal override void Awake() { base.Awake(); boomboxItem = ((Component)this).GetComponent<BoomboxItem>(); ((GrabbableObject)boomboxItem).itemProperties.requiresBattery = false; if (Patch.MuteAlways) { boomboxItem.boomboxAudio.mute = true; } } internal void Start() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) BoomboxControllers[((NetworkBehaviour)this).NetworkObjectId] = this; if (Config.BoomboxRandomColor && IsHostOrIsOffline()) { SyncBoomboxColor(GetRandomBoomboxColor(), colorPattern, GetColorPatternString(colorPattern), ((NetworkBehaviour)this).NetworkManager.LocalClientId); } } internal void SyncBoomboxColorRequestServerDelegate(float r, float g, float b, COLOR_PATTERN colorPattern = COLOR_PATTERN.NONE) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (Patch.IsOffline()) { if (!ApplyColorPattern(colorPattern, ((NetworkBehaviour)this).NetworkManager.LocalClientId)) { SyncBoomboxColorRequestClientShared(r, g, b, colorPattern, null, ((NetworkBehaviour)this).NetworkManager.LocalClientId, msg: true); } } else { SyncBoomboxColorRequestServerRpc(r, g, b, colorPattern); } } private void SyncBoomboxColor(Color color, COLOR_PATTERN colorPattern, string colorPatternString, ulong clientId, bool msg = false) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsHost) { SyncBoomboxColorRequestClientRpc(color.r, color.g, color.b, colorPattern, colorPatternString, clientId, msg); } else { SyncBoomboxColorRequestClientShared(color.r, color.g, color.b, colorPattern, colorPatternString, clientId, msg); } } [ServerRpc(RequireOwnership = false)] internal void SyncAllRequestServerRpc(ulong clientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4064489894u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, clientId); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4064489894u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!IsInvalidServerCall()) { Request request = GetRequest(((NetworkBehaviour)this).NetworkObjectId); if (request != null) { ClientRpcParams clientRpcParamsForClient = Controller.GetClientRpcParamsForClient(clientId); SyncVolumeRequestClientRpc(request.volume, 0uL, msg: false, clientRpcParamsForClient); Color boomboxBodyColor = GetBoomboxBodyColor(); SyncBoomboxColorRequestClientRpc(boomboxBodyColor.r, boomboxBodyColor.g, boomboxBodyColor.b, colorPattern, null, 0uL, msg: false, clientRpcParamsForClient); SyncRequestVerifyClientCall(request, clientRpcParamsForClient); } } } [ServerRpc(RequireOwnership = false)] private void SyncBoomboxColorRequestServerRpc(float r, float g, float b, COLOR_PATTERN colorPattern, ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2959672043u, serverRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref r, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref g, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref b, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<COLOR_PATTERN>(ref colorPattern, default(ForEnums)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 2959672043u, serverRpcParams, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!IsInvalidServerCall()) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (!ApplyColorPattern(colorPattern, senderClientId)) { SyncBoomboxColorRequestClientRpc(r, g, b, colorPattern, null, senderClientId, msg: true); } } } [ClientRpc] internal void SyncBoomboxColorRequestClientRpc(float r, float g, float b, COLOR_PATTERN colorPattern, string colorPatternString, ulong clientId, bool msg = false, ClientRpcParams clientRpcParams = default(ClientRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2185452183u, clientRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref r, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref g, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref b, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<COLOR_PATTERN>(ref colorPattern, default(ForEnums)); bool flag = colorPatternString != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(colorPatternString, false); } BytePacker.WriteValueBitPacked(val, clientId); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref msg, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2185452183u, clientRpcParams, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!IsInvalidClientCall()) { SyncBoomboxColorRequestClientShared(r, g, b, colorPattern, colorPatternString, clientId, msg); } } } internal override void StartAudio(float? forceTime = null) { if (IsItemActive()) { boomboxItem.boomboxAudio.pitch = 1f; boomboxItem.boomboxAudio.Play(); boomboxItem.isPlayingMusic = (((GrabbableObject)boomboxItem).isBeingUsed = true); StartAudioTime(forceTime); } } internal override void StopAudio(float? forceTime = null, bool syncTime = true) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (IsItemActive()) { StopAudioTime(forceTime); if (((NetworkBehaviour)this).IsHost && syncTime) { SyncTimeRequestServerRpc(timeSaved, REQUEST_TYPE.STOP); } bool isPlayingMusic = boomboxItem.isPlayingMusic; boomboxItem.boomboxAudio.Stop(); if (isPlayingMusic) { boomboxItem.boomboxAudio.PlayOneShot(boomboxItem.stopAudios[Random.Range(0, boomboxItem.stopAudios.Length)]); } boomboxItem.isPlayingMusic = (((GrabbableObject)boomboxItem).isBeingUsed = false); } } internal override REQUEST_STATE Sync(bool request, string filenameId, string url, string title, int duration, float time, AudioClip audioClip, bool isPlaying) { serverFilenameId = filenameId; serverUrl = url; serverTitle = title; serverDuration = duration; serverTime = time; if (!IsItemActive()) { return REQUEST_STATE.FAILURE; } if (Object.op_Implicit((Object)(object)audioClip)) { base.filenameId = filenameId; base.url = url; base.title = title; base.duration = duration; boomboxItem.boomboxAudio.clip = audioClip; boomboxItem.boomboxAudio.time = (timeSaved = Controller.ClampAudioSource(boomboxItem.boomboxAudio, time)); } else { ResetController(); time = 0f; } if (request) { if (((GrabbableObject)boomboxItem).isHeld) { if (isPlaying) { ResetAudio(time); } return REQUEST_STATE.SUCCESS; } StartAudio(time); return REQUEST_STATE.AUTO_PLAY; } if (isPlaying) { StartAudio(time); } else { StopAudio(time, syncTime: false); } return REQUEST_STATE.SUCCESS; } internal override void ResetController() { AudioSource audioSource = GetAudioSource(); audioSource.clip = GetDefaultAudioClip(); audioSource.time = 0f; ResetControllerBase(); } internal override Controller GetControllerForItemId(ulong itemId) { if (!BoomboxControllers.ContainsKey(itemId)) { return null; } return BoomboxControllers[itemId]; } internal override bool IsPlaying() { return boomboxItem.isPlayingMusic; } internal override bool IsResettable() { if (IsBoomboxHeldByUsOrUnattended(boomboxItem)) { return base.IsResettable(); } return false; } internal static bool IsBoomboxHeldByUsOrUnattended(BoomboxItem boomboxItem) { if (Object.op_Implicit((Object)(object)boomboxItem)) { if (!IsBoomboxHeldByUs(boomboxItem)) { return !((GrabbableObject)boomboxItem).isHeld; } return true; } return false; } internal static void ToggleMuteBoomboxItems(List<BoomboxItem> boomboxItems) { if (boomboxItems != null && boomboxItems.Count == 0) { return; } bool flag = Object.op_Implicit((Object)(object)boomboxItems.Find((BoomboxItem boomboxItem) => !boomboxItem.boomboxAudio.mute)); foreach (BoomboxItem boomboxItem in boomboxItems) { boomboxItem.boomboxAudio.mute = flag; } bool flag2 = boomboxItems.Count == 1; string text = (flag2 ? "boombox" : "boomboxes"); string text2 = (flag2 ? "it" : "them"); string text3 = (flag ? Patch.GetMutedString() : Patch.GetUnmutedString()); string text4 = (flag ? "unmute" : "mute"); Patch.AddChatMessage($"{boomboxItems.Count} {text} {text3} locally, to {text4} {text2} press [{Patch.TealColorString(((object)(KeyboardShortcut)(ref Config.KeyboardShortcutMute)).ToString())}]"); } internal static bool IsBoomboxHeldByUs(BoomboxItem boomboxItem) { if (Object.op_Implicit((Object)(object)boomboxItem) && Object.op_Implicit((Object)(object)Patch.LocalPlayerController) && Object.op_Implicit((Object)(object)((GrabbableObject)boomboxItem).playerHeldBy)) { return (Object)(object)((GrabbableObject)boomboxItem).playerHeldBy == (Object)(object)Patch.LocalPlayerController; } return false; } internal static bool IsBoomboxHeldBySomeoneElse(BoomboxItem boomboxItem) { if (Object.op_Implicit((Object)(object)boomboxItem) && Object.op_Implicit((Object)(object)Patch.LocalPlayerController) && Object.op_Implicit((Object)(object)((GrabbableObject)boomboxItem).playerHeldBy)) { return (Object)(object)((GrabbableObject)boomboxItem).playerHeldBy != (Object)(object)Patch.LocalPlayerController; } return false; } internal static bool IsBoomboxHeldBySomeoneElseOrUnattended(BoomboxItem boomboxItem) { if (Object.op_Implicit((Object)(object)boomboxItem)) { if (!IsBoomboxHeldBySomeoneElse(boomboxItem)) { return !((GrabbableObject)boomboxItem).isHeld; } return true; } return false; } internal static Color GetRandomBoomboxColor() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) float num = Random.Range(0f, 1f); float num2 = Random.Range(0f, 1f); float num3 = Random.Range(0f, 1f); return new Color(num, num2, num3); } internal static BoomboxItem GetHeldBoomboxItem(PlayerControllerB playerControllerB) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)playerControllerB)) { return null; } if (playerControllerB.currentItemSlot >= playerControllerB.ItemSlots.Length) { return null; } object obj = playerControllerB.ItemSlots[playerControllerB.currentItemSlot]; if (obj == null) { return null; } if (!(obj.GetType() == typeof(BoomboxItem))) { return null; } return (BoomboxItem)obj; } internal static List<BoomboxItem> GetHeldBoomboxItems(PlayerControllerB playerControllerB) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)playerControllerB)) { return new List<BoomboxItem>(); } List<BoomboxItem> list = new List<BoomboxItem>(); GrabbableObject[] array = playerControllerB.ItemSlots.ToArray(); foreach (object obj in array) { if (obj != null && obj.GetType() == typeof(BoomboxItem)) { list.Add((BoomboxItem)obj); } } return list; } internal void ToggleMutePlayer() { if (LookingPatch.LookingAtPlayerBoomboxItems.Count > 1) { ToggleMuteBoomboxItems(LookingPatch.LookingAtPlayerBoomboxItems.ToList()); } else { ToggleMute(); } } private bool ApplyColorPattern(COLOR_PATTERN colorPattern, ulong clientId) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (colorPatternCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(colorPatternCoroutine); } switch (colorPattern) { case COLOR_PATTERN.RANDOM_LOOP: ((MonoBehaviour)this).StartCoroutine(colorPatternCoroutine = ColorPatternRandomLoop(clientId)); return true; case COLOR_PATTERN.RAINBOW: SyncBoomboxColor(GetBoomboxBodyColor(), colorPattern, GetColorPatternString(colorPattern), clientId, msg: true); return true; default: return false; } } [IteratorStateMachine(typeof(<ColorPatternRandomLoop>d__31))] private IEnumerator ColorPatternRandomLoop(ulong clientId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ColorPatternRandomLoop>d__31(0) { <>4__this = this, clientId = clientId }; } [IteratorStateMachine(typeof(<ColorPatternRainbow>d__32))] private IEnumerator ColorPatternRainbow(ulong clientId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ColorPatternRainbow>d__32(0) { <>4__this = this }; } private static Color ColorShift(Color color, float amount) { //IL_0000: 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) float num2 = default(float); float num3 = default(float); float num = default(float); Color.RGBToHSV(color, ref num, ref num2, ref num3); num += amount; return Color.HSVToRGB(num, 1f, 1f); } private string GetColorPatternString(COLOR_PATTERN colorPattern) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) switch (colorPattern) { case COLOR_PATTERN.RANDOM_LOOP: { string text2; if (colorPatternRandomTextColors.Count > 0) { List<string> list3 = new List<string>(); int num = 0; string text = "RANDOM"; for (int i = 0; i < text.Length; i++) { string str = text[i].ToString(); string color2 = Patch.ColorToHex(colorPatternRandomTextColors[num++]); list3.Add(Patch.ColorString(str, color2)); } text2 = string.Concat(list3); } else { text2 = "RANDOM"; } return text2 + " loop"; } case COLOR_PATTERN.RAINBOW: { List<string> list = colorPatternRainbowDict.Keys.ToList(); List<string> list2 = new List<string>(); foreach (string item in list) { Color value = Patch.ParseColor(colorPatternRainbowDict[item]).Value; string color = Patch.ColorToHex(value); list2.Add(Patch.ColorString(item, color)); } return string.Concat(string.Concat(list2), "!"); } default: return null; } } internal override void SyncAllRequestServer(ulong clientId) { SyncAllRequestServerRpc(clientId); } internal override AudioSource GetAudioSource() { return boomboxItem.boomboxAudio; } internal override string GetSetTimeString(float time) { return string.Format("{0} set to {1} seconds", IsBoomboxHeldByUs(boomboxItem) ? "Your boombox playback time was" : "Boombox playback time", Math.Round(time, 1)); } internal override AudioClip GetDefaultAudioClip() { if (boomboxItem.musicAudios.Length == 0) { return null; } return boomboxItem.musicAudios[boomboxItem.musicRandomizer.Next(0, boomboxItem.musicAudios.Length)]; } internal Color GetBoomboxBodyColor() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) return ((Renderer)((Component)boomboxItem).gameObject.GetComponent<MeshRenderer>()).materials[3].color; } internal bool ShouldResyncColor(float r, float g, float b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Color boomboxBodyColor = GetBoomboxBodyColor(); if (r == boomboxBodyColor.r && g == boomboxBodyColor.g) { return b != boomboxBodyColor.b; } return true; } internal void SyncBoomboxColorRequestClientShared(float r, float g, float b, COLOR_PATTERN colorPattern, string colorPatternString, ulong clientId, bool msg = false) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (!IsItemActive()) { return; } Color? val = ChangeBoomboxColor(r, g, b); if (!val.HasValue) { if (msg) { Patch.AddChatMessage("Failed to change boombox color."); } return; } if (colorPatternCoroutine != null && this.colorPattern != colorPattern) { ((MonoBehaviour)this).StopCoroutine(colorPatternCoroutine); } if (colorPattern == COLOR_PATTERN.RAINBOW) { ((MonoBehaviour)this).StartCoroutine(colorPatternCoroutine = ColorPatternRainbow(clientId)); } this.colorPattern = colorPattern; if (msg && IsClientIdLocal(clientId)) { string text = (IsBoomboxHeldByUs(boomboxItem) ? "Your boombox color was" : "Boombox color"); if (colorPatternString == null) { colorPatternString = Patch.ColorToString(val.Value); } Patch.AddChatMessage(text + " set to " + colorPatternString); } } internal Color? ChangeBoomboxColor(float r, float g, float b) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (!IsItemActive()) { return null; } r = Mathf.Clamp(r, 0f, 1f); g = Mathf.Clamp(g, 0f, 1f); b = Mathf.Clamp(b, 0f, 1f); Color val = default(Color); ((Color)(ref val))..ctor(r, g, b); MeshRenderer component = ((Component)boomboxItem).gameObject.GetComponent<MeshRenderer>(); if (!Object.op_Implicit((Object)(object)component)) { return null; } ((Renderer)component).materials[1].color = val; ((Renderer)component).materials[3].color = val; return val; } internal override ITEM_TYPE GetItemType() { return ITEM_TYPE.BOOMBOX; } internal override string GetItemName() { return "Boombox"; } internal override bool IsItemActive() { return IsBoomboxItemActive(boomboxItem); } internal static bool IsBoomboxItemActive(BoomboxItem boomboxItem) { return Controller.IsNetworkBehaviourActive((NetworkBehaviour)(object)boomboxItem); } internal override bool IsBeingUsedByUs() { return IsBoomboxHeldByUs(boomboxItem); } protected override void __initializeVariables() { base.__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(4064489894u, new RpcReceiveHandler(__rpc_handler_4064489894), "SyncAllRequestServerRpc"); ((NetworkBehaviour)this).__registerRpc(2959672043u, new RpcReceiveHandler(__rpc_handler_2959672043), "SyncBoomboxColorRequestServerRpc"); ((NetworkBehaviour)this).__registerRpc(2185452183u, new RpcReceiveHandler(__rpc_handler_2185452183), "SyncBoomboxColorRequestClientRpc"); base.__initializeRpcs(); } private static void __rpc_handler_4064489894(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong clientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref clientId); target.__rpc_exec_stage = (__RpcExecStage)1; ((BoomboxController)(object)target).SyncAllRequestServerRpc(clientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2959672043(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float r = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref r, default(ForPrimitives)); float g = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref g, default(ForPrimitives)); float b = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref b, default(ForPrimitives)); COLOR_PATTERN cOLOR_PATTERN = default(COLOR_PATTERN); ((FastBufferReader)(ref reader)).ReadValueSafe<COLOR_PATTERN>(ref cOLOR_PATTERN, default(ForEnums)); ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((BoomboxController)(object)target).SyncBoomboxColorRequestServerRpc(r, g, b, cOLOR_PATTERN, server); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2185452183(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float r = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref r, default(ForPrimitives)); float g = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref g, default(ForPrimitives)); float b = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref b, default(ForPrimitives)); COLOR_PATTERN cOLOR_PATTERN = default(COLOR_PATTERN); ((FastBufferReader)(ref reader)).ReadValueSafe<COLOR_PATTERN>(ref cOLOR_PATTERN, default(ForEnums)); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); string colorPatternString = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref colorPatternString, false); } ulong clientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref clientId); bool msg = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref msg, default(ForPrimitives)); ClientRpcParams client = rpcParams.Client; target.__rpc_exec_stage = (__RpcExecStage)1; ((BoomboxController)(object)target).SyncBoomboxColorRequestClientRpc(r, g, b, cOLOR_PATTERN, colorPatternString, clientId, msg, client); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "BoomboxController"; } } internal enum ACTION_STATE { PROCESSING, KILLED, FINISHED } internal enum REQUEST_TYPE { TIME, STOP } internal enum REQUEST_STATE { FAILURE, AUTO_PLAY, SUCCESS } internal enum REQUEST_STATUS { NONE, REQUEST_INITIALIZING, REQUEST_VALID, REQUEST_CANCELED, REQUEST_TIMEOUT, REQUEST_NEW_REQUEST, ERROR_CLIENT_DOWNLOAD, ERROR_CLIENT_DOWNLOAD_CANCELED, ERROR_CLIENT_DOWNLOAD_EXCEPTION, ERROR_CLIENT_LOAD, ERROR_CLIENT_TIMEOUT, ERROR_CLIENT_DISCONNECT, ERROR_CLIENT_OFFLINE, ERROR_UTIL_MISSING_DEPENDENCY, ERROR_UTIL_DOWNLOADING_TOOLS, ERROR_INVALID_TOOLS, ERROR_INVALID_ITEM, ERROR_INVALID_URL, ERROR_METADATA, ERROR_METADATA_EXCEPTION, ERROR_METADATA_AGE_RESTRICTED, ERROR_METADATA_BOT, ERROR_METADATA_SIGN_IN, ERROR_METADATA_VIDEO_UNAVAILABLE, ERROR_METADATA_MAX_DURATION } internal enum MUTE { NONE, SINGLE, ALL, ALWAYS } internal enum NETWORK_MODE { OFFLINE, ONLINE } internal enum COLOR_PATTERN { NONE, RANDOM_LOOP, RAINBOW } internal enum TOOLS_STATUS { NONE, DOWNLOADING } internal enum ITEM_TYPE { BOOMBOX, CRUISER } internal enum CRUISER_COMPONENT { NONE, TURN_ON_RADIO, CHANGE_CHANNEL } internal class Request { internal string filenameId; internal string url; internal string title; internal int duration; internal float time; internal float volume; internal bool isPlaying; public Request(string filenameId, string url, string title, int duration, float time, float volume, bool isPlaying) { this.filenameId = filenameId; this.url = url; this.title = title; this.duration = duration; this.time = time; this.volume = volume; this.isPlaying = isPlaying; base..ctor(); } } internal class Config { internal static string BindingCategorySettings = "Settings"; internal static string BindingCategoryKeybinds = "Keybinds"; private static ConfigEntry<bool> ConfigEntrySync; private static ConfigEntry<bool> ConfigEntryPocketPlay; private static ConfigEntry<bool> ConfigEntryBoomboxRandomColor; public static bool Sync; public static bool PocketPlay; public static bool BoomboxRandomColor; internal static ConfigEntry<KeyboardShortcut> KeyboardShortcutSync; internal static ConfigEntry<KeyboardShortcut> KeyboardShortcutReset; internal static KeyboardShortcut KeyboardShortcutMute; internal static ConfigEntry<KeyboardShortcut> KeyboardShortcutVolumeUp; internal static ConfigEntry<KeyboardShortcut> KeyboardShortcutVolumeDown; internal static ConfigEntry<KeyboardShortcut> KeyboardShortcutHistoryNext; internal static ConfigEntry<KeyboardShortcut> KeyboardShortcutHistoryPrevious; internal Config(ConfigFile configFile) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) ConfigEntrySync = configFile.Bind<bool>(BindingCategorySettings, "Sync", false, "[HOST] Copy the audio and time of another boombox or cruiser, and allow them to play the same audio. NOTE: This is resource intensive but offers more features and accurate syncing."); ConfigEntryPocketPlay = configFile.Bind<bool>(BindingCategorySettings, "Pocket play", false, "[HOST] Allows the boombox to continue playing in the inventory."); ConfigEntryBoomboxRandomColor = configFile.Bind<bool>(BindingCategorySettings, "Boombox random color", false, "[HOST] Boomboxes are spawned with a random color!"); KeyboardShortcutSync = configFile.Bind<KeyboardShortcut>(BindingCategoryKeybinds, "Sync keybind", new KeyboardShortcut((KeyCode)113, Array.Empty<KeyCode>()), "Sync to another boombox or cruiser, or resync (redownload) the audio."); KeyboardShortcutReset = configFile.Bind<KeyboardShortcut>(BindingCategoryKeybinds, "Reset keybind", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), "Reset the playback time to 0 and stop playback."); KeyboardShortcutMute = new KeyboardShortcut((KeyCode)8, Array.Empty<KeyCode>()); KeyboardShortcutVolumeUp = configFile.Bind<KeyboardShortcut>(BindingCategoryKeybinds, "Boombox volume up keybind", new KeyboardShortcut((KeyCode)280, Array.Empty<KeyCode>()), "Increase the boombox volume."); KeyboardShortcutVolumeDown = configFile.Bind<KeyboardShortcut>(BindingCategoryKeybinds, "Boombox volume down keybind", new KeyboardShortcut((KeyCode)281, Array.Empty<KeyCode>()), "Decrease the boombox volume."); KeyboardShortcutHistoryNext = configFile.Bind<KeyboardShortcut>(BindingCategoryKeybinds, "Play history next keybind", new KeyboardShortcut((KeyCode)275, Array.Empty<KeyCode>()), "Navigate to the next page in your play history."); KeyboardShortcutHistoryPrevious = configFile.Bind<KeyboardShortcut>(BindingCategoryKeybinds, "Play history previous keybind", new KeyboardShortcut((KeyCode)276, Array.Empty<KeyCode>()), "Navigate to the previous page in your play history."); MigrateAndClearOrphanedEntries(configFile); Sync = ConfigEntrySync.Value; PocketPlay = ConfigEntryPocketPlay.Value; BoomboxRandomColor = ConfigEntryBoomboxRandomColor.Value; } private void MigrateAndClearOrphanedEntries(ConfigFile configFile) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown Dictionary<ConfigDefinition, ConfigEntryBase> dictionary = new Dictionary<ConfigDefinition, ConfigEntryBase> { { new ConfigDefinition(BindingCategorySettings, "Boombox sync"), (ConfigEntryBase)(object)ConfigEntrySync }, { new ConfigDefinition(BindingCategorySettings, "Boombox pocket play"), (ConfigEntryBase)(object)ConfigEntryPocketPlay }, { new ConfigDefinition(BindingCategoryKeybinds, "Sync boombox keybind"), (ConfigEntryBase)(object)KeyboardShortcutSync }, { new ConfigDefinition(BindingCategoryKeybinds, "Reset boombox keybind"), (ConfigEntryBase)(object)KeyboardShortcutReset } }; PropertyInfo property = ((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary<ConfigDefinition, string> dictionary2 = (Dictionary<ConfigDefinition, string>)property.GetValue(configFile, null); foreach (KeyValuePair<ConfigDefinition, string> item in dictionary2) { if (dictionary.TryGetValue(item.Key, out var value)) { value.SetSerializedValue(item.Value); YPlay.LogInfo("Config migrated: [" + item.Key.Key + "] > [" + value.Definition.Key + "]: " + item.Value); } } dictionary2.Clear(); configFile.Save(); } internal static void SetConfigEntrySync(bool b) { ConfigEntrySync.Value = b; } internal static void SetConfigEntryPocketPlay(bool b) { ConfigEntryPocketPlay.Value = b; } internal static void SetConfigEntryBoomboxRandomColor(bool b) { ConfigEntryBoomboxRandomColor.Value = b; } } internal class RequestMetadata { private static int GlobalRequestId; internal HashSet<ulong> originalClientIdRequests = new HashSet<ulong>(); internal HashSet<ulong> pendingClientIdRequests = new HashSet<ulong>(); internal REQUEST_STATUS requestStatus = REQUEST_STATUS.REQUEST_INITIALIZING; internal int requestId = GlobalRequestId++; internal string filenameId; internal string title; internal string url; internal float time; internal int duration; } internal class CommandBuilder { internal string url; internal float time; internal float volume = 1f; internal string historyUrl; internal Color color; internal COLOR_PATTERN colorPattern; internal MUTE muteMode = MUTE.SINGLE; internal bool urlUrlSet; internal bool urlSet; internal bool offlineSet; internal bool historySet; internal bool muteSet; internal bool timeSet; internal bool actionsSet; internal bool helpSet; internal bool statusSet; internal bool updateSet; internal bool settingsSet; internal bool syncSet; internal bool pocketPlaySet; internal bool boomboxRandomColorSet; internal bool volumeSet; internal bool colorSet; internal bool urlSuccess; internal bool timeSuccess; internal bool volumeSuccess; internal bool colorSuccess; internal bool historyUrlIndexFailed; } internal static class YPlayConfig { internal const int MaxChatCharacters = 50; internal const int PlayHistoryResultsPerPage = 3; internal const int PlayHistoryResultsMax = 15; internal const int MaxClips = 15; internal const int MaxAudioLengthMinutes = 12; internal const float MinVolume = 0f; internal const float MaxVolume = 1f; internal const int DownloadMetadataTimeoutMs = 15000; internal const int DownloadAudioTimeoutBaseMs = 27000; internal const int DownloadRequestWaitMs = 5000; } internal static class Patch { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__MessageHandlerPocketPlayClient; public static HandleNamedMessageDelegate <1>__MessageHandlerSyncEnabledClient; public static HandleNamedMessageDelegate <2>__MessageHandlerBoomboxRandomColorClient; public static HandleNamedMessageDelegate <3>__MessageHandlerMessageClient; public static HandleNamedMessageDelegate <4>__MessageHandlerSyncRequestServer; public static HandleNamedMessageDelegate <5>__MessageHandlerModEnabledServer; public static HandleNamedMessageDelegate <6>__MessageHandlerModeServer; public static HandleNamedMessageDelegate <7>__MessageHandlerSyncRequestClient; } internal static NETWORK_MODE NetworkMode = NETWORK_MODE.OFFLINE; private static readonly HashSet<string> ConflictingBoomboxModNames = new HashSet<string>(); internal static readonly HashSet<ulong> ModEnabledForClientIds = new HashSet<ulong>(); internal static bool MuteAlways; internal static string MuteAlwaysSymbol = PinkColorString("*"); internal const string InvalidYouTubeURLString = "Invalid YouTube URL, please check it is valid"; private const string VersionMismatchErrorString = "No response from the host, they may not have YPlayBoombox installed"; private const string ClientOnlyCommandString = "Sorry, hosts can't use this command!"; private const string HostOnlyCommandString = "Sorry, this command can only be used by the host"; private const string HostOrOfflineOnlyCommandString = "Sorry, this command can only be used by the host or while in offline mode"; private static bool VersionMismatchErrorStringShown = false; private static readonly Type TypeAddChatMessage = typeof(HUDManager); private static readonly MethodInfo MethodInfoAddChatMessage = TypeAddChatMessage.GetMethod("AddChatMessage", BindingFlags.Instance | BindingFlags.NonPublic); private const string ConfigTag = "[CONFIG]"; private static readonly string[] InvalidFilenameIds = new string[3] { "results", "search", "search_query" }; private static CancellationTokenSource syncedCancellationTokenSource; private static string serverModVersion; private static readonly string MessageHandlerModEnabledS = GetMessageHandlerKey("MessageHandlerModEnabledS"); private static readonly string MessageHandlerModeS = GetMessageHandlerKey("MessageHandlerModeS"); private static readonly string MessageHandlerPocketPlayC = GetMessageHandlerKey("MessageHandlerPocketPlayC"); private static readonly string MessageHandlerSyncEnabledC = GetMessageHandlerKey("MessageHandlerSyncEnabledC"); private static readonly string MessageHandlerBoomboxRandomColorC = GetMessageHandlerKey("MessageHandlerBoomboxRandomColorC"); private static readonly string MessageHandlerSyncRequestS = GetMessageHandlerKey("MessageHandlerSyncRequestS"); private static readonly string MessageHandlerSyncRequestC = GetMessageHandlerKey("MessageHandlerSyncRequestC"); private static readonly string MessageHandlerMessageHandlerC = GetMessageHandlerKey("MessageHandlerMessageHandlerC"); internal static readonly HashSet<VehicleController> VehicleControllers = new HashSet<VehicleController>(); private static string LastChatCommandMessage; private static float LastChatMessageTime; private const float SameChatMessageTimeMin = 0.1f; private static readonly List<string> PlayHistoryUrls = new List<string>(); private static bool InPlayHistory; private static int PlayHistoryPage; private static string PlayHistoryNavigatePreviousString; private static string PlayHistoryNavigateNextString; private static CustomMessagingManager CustomMessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsHost => NetworkManager.Singleton.IsHost; internal static PlayerControllerB LocalPlayerController => StartOfRound.Instance.localPlayerController; private static string GetMessageHandlerKey(string name) { return "YPlayBoombox_" + name; } [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPrefix] internal static void GameNetworkManager_Start_Patch(GameNetworkManager __instance) { bool flag = false; bool flag2 = false; foreach (NetworkPrefab prefab in ((Component)__instance).GetComponent<NetworkManager>().NetworkConfig.Prefabs.Prefabs) { if (!flag && Object.op_Implicit((Object)(object)prefab.Prefab.GetComponent<BoomboxItem>())) { prefab.Prefab.AddComponent<BoomboxController>(); flag = true; } else if (!flag2 && Object.op_Implicit((Object)(object)prefab.Prefab.GetComponent<VehicleController>())) { prefab.Prefab.AddComponent<CruiserController>(); flag2 = true; } if (flag && flag2) { break; } } CheckConflictingBoomboxMods(); } [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] [HarmonyPostfix] internal static void OnClientConnect_Patch(StartOfRound __instance, ulong clientId) { Controller.shouldVerify = true; } [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPrefix] internal static void PlayerControllerB_ConnectClientToPlayerObject_Patch(PlayerControllerB __instance) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown NetworkMode = (IsHost ? NETWORK_MODE.ONLINE : NETWORK_MODE.OFFLINE); serverModVersion = (IsHost ? "2.6.0" : null); SetPocketPlay(Config.PocketPlay); SetSyncEnabled(Config.Sync); SetBoomboxRandomColor(Config.BoomboxRandomColor); CustomMessagingManager customMessageManager = CustomMessageManager; string messageHandlerPocketPlayC = MessageHandlerPocketPlayC; object obj = <>O.<0>__MessageHandlerPocketPlayClient; if (obj == null) { HandleNamedMessageDelegate val = MessageHandlerPocketPlayClient; <>O.<0>__MessageHandlerPocketPlayClient = val; obj = (object)val; } customMessageManager.RegisterNamedMessageHandler(messageHandlerPocketPlayC, (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessageManager2 = CustomMessageManager; string messageHandlerSyncEnabledC = MessageHandlerSyncEnabledC; object obj2 = <>O.<1>__MessageHandlerSyncEnabledClient; if (obj2 == null) { HandleNamedMessageDelegate val2 = MessageHandlerSyncEnabledClient; <>O.<1>__MessageHandlerSyncEnabledClient = val2; obj2 = (object)val2; } customMessageManager2.RegisterNamedMessageHandler(messageHandlerSyncEnabledC, (HandleNamedMessageDelegate)obj2); CustomMessagingManager customMessageManager3 = CustomMessageManager; string messageHandlerBoomboxRandomColorC = MessageHandlerBoomboxRandomColorC; object obj3 = <>O.<2>__MessageHandlerBoomboxRandomColorClient; if (obj3 == null) { HandleNamedMessageDelegate val3 = MessageHandlerBoomboxRandomColorClient; <>O.<2>__MessageHandlerBoomboxRandomColorClient = val3; obj3 = (object)val3; } customMessageManager3.RegisterNamedMessageHandler(messageHandlerBoomboxRandomColorC, (HandleNamedMessageDelegate)obj3); CustomMessagingManager customMessageManager4 = CustomMessageManager; string messageHandlerMessageHandlerC = MessageHandlerMessageHandlerC; object obj4 = <>O.<3>__MessageHandlerMessageClient; if (obj4 == null) { HandleNamedMessageDelegate val4 = MessageHandlerMessageClient; <>O.<3>__MessageHandlerMessageClient = val4; obj4 = (object)val4; } customMessageManager4.RegisterNamedMessageHandler(messageHandlerMessageHandlerC, (HandleNamedMessageDelegate)obj4); if (IsHost) { CustomMessagingManager customMessageManager5 = CustomMessageManager; string messageHandlerSyncRequestS = MessageHandlerSyncRequestS; object obj5 = <>O.<4>__MessageHandlerSyncRequestServer; if (obj5 == null) { HandleNamedMessageDelegate val5 = MessageHandlerSyncRequestServer; <>O.<4>__MessageHandlerSyncRequestServer = val5; obj5 = (object)val5; } customMessageManager5.RegisterNamedMessageHandler(messageHandlerSyncRequestS, (HandleNamedMessageDelegate)obj5); CustomMessagingManager customMessageManager6 = CustomMessageManager; string messageHandlerModEnabledS = MessageHandlerModEnabledS; object obj6 = <>O.<5>__MessageHandlerModEnabledServer; if (obj6 == null) { HandleNamedMessageDelegate val6 = MessageHandlerModEnabledServer; <>O.<5>__MessageHandlerModEnabledServer = val6; obj6 = (object)val6; } customMessageManager6.RegisterNamedMessageHandler(messageHandlerModEnabledS, (HandleNamedMessageDelegate)obj6); CustomMessagingManager customMessageManager7 = CustomMessageManager; string messageHandlerModeS = MessageHandlerModeS; object obj7 = <>O.<6>__MessageHandlerModeServer; if (obj7 == null) { HandleNamedMessageDelegate val7 = MessageHandlerModeServer; <>O.<6>__MessageHandlerModeServer = val7; obj7 = (object)val7; } customMessageManager7.RegisterNamedMessageHandler(messageHandlerModeS, (HandleNamedMessageDelegate)obj7); SetModEnabled(__instance.actualClientId, "2.6.0"); } else { CustomMessagingManager customMessageManager8 = CustomMessageManager; string messageHandlerSyncRequestC = MessageHandlerSyncRequestC; object obj8 = <>O.<7>__MessageHandlerSyncRequestClient; if (obj8 == null) { HandleNamedMessageDelegate val8 = MessageHandlerSyncRequestClient; <>O.<7>__MessageHandlerSyncRequestClient = val8; obj8 = (object)val8; } customMessageManager8.RegisterNamedMessageHandler(messageHandlerSyncRequestC, (HandleNamedMessageDelegate)obj8); InitializeClient(); } YPlay.LogInfo("Successfully initialized"); } [HarmonyPatch(typeof(NetworkObject), "Spawn")] [HarmonyPrefix] internal static void NetworkObject_Spawn_Patch(NetworkObject __instance) { ApplyControllers(((Component)__instance).gameObject); } [HarmonyPatch(typeof(BoomboxItem), "StartMusic")] [HarmonyPrefix] internal static bool BoomboxItem_StartMusic_Patch(BoomboxItem __instance, bool startMusic, bool pitchDown) { ulong networkObjectId = ((NetworkBehaviour)__instance).NetworkObjectId; if (startMusic && BoomboxController.IsBoomboxHeldByUs(__instance)) { if (__instance.boomboxAudio.mute) { __instance.boomboxAudio.mute = false; AddChatMessage("Your boombox was " + GetUnmutedString() + " locally automatically"); Controller.VolumeZeroHint(__instance); } else { Controller.MutedVolumeZeroHint(__instance); } } if (!Object.op_Implicit((Object)(object)__instance.boomboxAudio.clip)) { return true; } if (!BoomboxController.BoomboxControllers.ContainsKey(networkObjectId)) { return true; } BoomboxController boomboxController = BoomboxController.BoomboxControllers[networkObjectId]; if (!boomboxController.IsAudioLoadedInMemory()) { if (startMusic && !string.IsNullOrEmpty(boomboxController.serverFilenameId?.Trim())) { boomboxController.StopControllersIfStealable(); } return true; } if (startMusic) { boomboxController.StartAudio(); } else if (__instance.isPlayingMusic) { boomboxController.StopAudio(); } return false; } [HarmonyPatch(typeof(VehicleController), "SetRadioValues")] [HarmonyPrefix] internal static void VehicleController_SetRadioValues_Patch(VehicleController __instance) { __instance.radioAudio.volume = 1f; __instance.radioInterference.volume = 0f; CruiserController.FieldInfoRadioSignalQuality.SetValue(__instance, 3); } [HarmonyPatch(typeof(VehicleController), "SetRadioOnLocalClient")] [HarmonyPrefix] internal static void VehicleController_SetRadioOnLocalClient_Patch(VehicleController __instance, bool on, bool setClip) { float f = (__instance.radioAudio.time = 0f); CruiserController.SetCurrentSongTime(__instance, f); ulong networkObjectId = ((NetworkBehaviour)__instance).NetworkObjectId; CruiserController cruiserController = null; if (CruiserController.CruiserControllers.ContainsKey(networkObjectId)) { cruiserController = CruiserController.CruiserControllers[networkObjectId]; } if (on && Object.op_Implicit((Object)(object)cruiserController)) { if (cruiserController.IsOnValidFirstClip()) { cruiserController.StopControllersIfStealable(); f = (__instance.radioAudio.time = Controller.ClampAudioSource(__instance.radioAudio, cruiserController.timeSaved)); CruiserController.SetCurrentSongTime(__instance, f); } else if (CruiserController.IsFirstClip(__instance) && !string.IsNullOrEmpty(cruiserController.serverFilenameId?.Trim())) { cruiserController.StopControllersIfStealable(); } } } [HarmonyPatch(typeof(VehicleController), "SetRadioStationClientRpc")] [HarmonyPostfix] [ClientRpc] internal static void VehicleController_SetRadioStation_Postfix_ClientRpc(VehicleController __instance, int radioStation, int signalQuality) { __instance.radioAudio.clip = __instance.radioClips[radioStation]; float f = (__instance.radioAudio.time = 0f); CruiserController.SetCurrentSongTime(__instance, f); __instance.radioAudio.Play(); } [HarmonyPatch(typeof(VehicleController), "ChangeRadioStation")] [HarmonyPrefix] internal static void VehicleController_ChangeRadioStation_Patch(VehicleController __instance) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) float f = (__instance.radioAudio.time = 0f); CruiserController.SetCurrentSongTime(__instance, f); ulong networkObjectId = ((NetworkBehaviour)__instance).NetworkObjectId; CruiserController cruiserController = null; if (CruiserController.CruiserControllers.ContainsKey(networkObjectId)) { cruiserController = CruiserController.CruiserControllers[networkObjectId]; } if (!Object.op_Implicit((Object)(object)cruiserController) || !cruiserController.IsFirstClipLoaded()) { return; } bool flag = CruiserController.IsRadioOn(__instance); int currentRadioStation = CruiserController.GetCurrentRadioStation(__instance); int num2 = (currentRadioStation + 1) % __instance.radioClips.Length; bool flag2 = cruiserController.IsOnValidFirstClip(); bool flag3 = num2 == 0; if (!(flag2 || flag3)) { return; } if (flag) { if (flag2) { cruiserController.SyncTimeRequestServerRpc(cruiserController.timeSaved = 0f, REQUEST_TYPE.STOP); } } else { CruiserController.FieldInfoRadioOn.SetValue(__instance, true); __instance.radioInterference.Play(); } if ((flag3 && __instance.radioClips.Length > 1) || __instance.radioClips.Length == 1) { cruiserController.StopControllersIfStealable(); } } [HarmonyPatch(typeof(VehicleController), "SwitchRadio")] [HarmonyPrefix] internal static bool VehicleController_SwitchRadio_Patch(VehicleController __instance) { ulong networkObjectId = ((NetworkBehaviour)__instance).NetworkObjectId; CruiserController cruiserController = null; if (CruiserController.CruiserControllers.ContainsKey(networkObjectId)) { cruiserController = CruiserController.CruiserControllers[networkObjectId]; } if (!Object.op_Implicit((Object)(object)cruiserController) || !cruiserController.IsOnValidFirstClip()) { return true; } CruiserController.FieldInfoRadioOn.SetValue(__instance, !CruiserController.IsRadioOn(__instance)); if (CruiserController.IsRadioOn(__instance)) { __instance.radioAudio.clip = __instance.radioClips[CruiserController.GetCurrentRadioStation(__instance)]; float f = (__instance.radioAudio.time = Controller.ClampAudioSource(__instance.radioAudio, cruiserController.timeSaved)); CruiserController.SetCurrentSongTime(__instance, f); cruiserController.StartAudio(); __instance.radioInterference.Play(); } else { cruiserController.StopAudio(); __instance.radioInterference.Stop(); } return false; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] internal static void PlayerControllerB_Update_Patch(PlayerControllerB __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)LocalPlayerController || !PlayerCanInteract(__instance)) { return; } KeyboardShortcut value; if (InPlayHistory && PlayHistoryUrls.Count > 0) { if (!string.IsNullOrEmpty(PlayHistoryNavigatePreviousString?.Trim())) { value = Config.KeyboardShortcutHistoryPrevious.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ShowPlayHistory(PlayHistoryPage - 1); return; } } if (!string.IsNullOrEmpty(PlayHistoryNavigateNextString?.Trim())) { value = Config.KeyboardShortcutHistoryNext.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ShowPlayHistory(PlayHistoryPage + 1); return; } } } BoomboxController boomboxController = null; BoomboxItem heldBoomboxItem = BoomboxController.GetHeldBoomboxItem(__instance); if (Object.op_Implicit((Object)(object)heldBoomboxItem)) { ulong networkObjectId = ((NetworkBehaviour)heldBoomboxItem).NetworkObjectId; if (BoomboxController.BoomboxControllers.ContainsKey(networkObjectId)) { boomboxController = BoomboxController.BoomboxControllers[networkObjectId]; } } BoomboxController boomboxController2 = null; BoomboxItem lookingAtBoomboxItem = LookingPatch.LookingAtBoomboxItem; if (Object.op_Implicit((Object)(object)lookingAtBoomboxItem)) { ulong networkObjectId2 = ((NetworkBehaviour)lookingAtBoomboxItem).NetworkObjectId; if (BoomboxController.BoomboxControllers.ContainsKey(networkObjectId2)) { boomboxController2 = BoomboxController.BoomboxControllers[networkObjectId2]; } } BoomboxController boomboxController3 = null; BoomboxItem lookingAtPlayerBoomboxItem = LookingPatch.LookingAtPlayerBoomboxItem; if (Object.op_Implicit((Object)(object)lookingAtPlayerBoomboxItem)) { ulong networkObjectId3 = ((NetworkBehaviour)lookingAtPlayerBoomboxItem).NetworkObjectId; if (BoomboxController.BoomboxControllers.ContainsKey(networkObjectId3)) { boomboxController3 = BoomboxController.BoomboxControllers[networkObjectId3]; } } BoomboxController boomboxController4 = boomboxController3 ?? boomboxController2; CruiserController cruiserController = null; VehicleController playerVehicleController = CruiserController.GetPlayerVehicleController(__instance); if (Object.op_Implicit((Object)(object)playerVehicleController)) { ulong networkObjectId4 = ((NetworkBehaviour)playerVehicleController).NetworkObjectId; if (CruiserController.CruiserControllers.ContainsKey(networkObjectId4)) { cruiserController = CruiserController.CruiserControllers[networkObjectId4]; } } CruiserController cruiserController2 = null; VehicleController lookingAtVehicleController = LookingPatch.LookingAtVehicleController; if (Object.op_Implicit((Object)(object)lookingAtVehicleController)) { ulong networkObjectId5 = ((NetworkBehaviour)lookingAtVehicleController).NetworkObjectId; if (CruiserController.CruiserControllers.ContainsKey(networkObjectId5)) { cruiserController2 = CruiserController.CruiserControllers[networkObjectId5]; } } value = Config.KeyboardShortcutSync.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { if (Object.op_Implicit((Object)(object)lookingAtPlayerBoomboxItem) && LookingPatch.LookingAtPlayerBoomboxItems.Count > 1) { bool flag = false; foreach (BoomboxItem item in LookingPatch.LookingAtPlayerBoomboxItems.ToList()) { ulong networkObjectId6 = ((NetworkBehaviour)item).NetworkObjectId; if (BoomboxController.BoomboxControllers.ContainsKey(networkObjectId6)) { BoomboxController boomboxController5 = BoomboxController.BoomboxControllers[networkObjectId6]; if (boomboxController5.IsResyncable()) { boomboxController5.Resync(); flag = true; } } } if (flag) { return; } } Controller controller = (Controller)(((object)boomboxController4) ?? ((object)cruiserController2)); if (Object.op_Implicit((Object)(object)controller) && controller.IsResyncable()) { controller.Resync(); return; } Controller controller2 = (Controller)(((object)cruiserController) ?? ((object)boomboxController)); if (Object.op_Implicit((Object)(object)controller2) && (Object)(object)controller2 != (Object)(object)controller && Object.op_Implicit((Object)(object)controller) && controller.IsSyncable()) { if (controller2.ShouldResync(controller)) { controller2.SyncRequestLookingAtServerDelegate(((NetworkBehaviour)controller).NetworkObjectId); } else { AddChatMessage(controller2.GetItemName() + " already synced"); } return; } } if (((KeyboardShortcut)(ref Config.KeyboardShortcutMute)).IsDown()) { if (Object.op_Implicit((Object)(object)boomboxController3)) { boomboxController3.ToggleMutePlayer(); return; } Controller controller3 = (Controller)(boomboxController4 ?? cruiserController2 ?? ((object)cruiserController) ?? ((object)boomboxController)); if (Object.op_Implicit((Object)(object)controller3)) { controller3.ToggleMute(); return; } } value = Config.KeyboardShortcutReset.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Controller controller4 = (Controller)(boomboxController2 ?? ((object)cruiserController2) ?? ((object)boomboxController)); if (Object.op_Implicit((Object)(object)controller4) && controller4.IsResettable()) { controller4.ResetRequestServerDelegate(); return; } } Controller controller5 = boomboxController2 ?? boomboxController; if (!Object.op_Implicit((Object)(object)controller5)) { return; } value = Config.KeyboardShortcutVolumeUp.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { controller5.IncrementVolume(); return; } value = Config.KeyboardShortcutVolumeDown.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { controller5.DecrementVolume(); } } [HarmonyPatch(typeof(HUDManager), "Start")] [HarmonyPrefix] internal static void HUDManager_Start_Patch(HUDManager __instance) { __instance.chatTextField.characterLimit = GetChatCharacterLimit(); if (!YPlay.IsYPlayUtilValid()) { AddChatMessage("Missing dependency, please try reinstalling YPlayBoombox"); } if (YPlay.IsDownloadingTools()) { AddChatMessage("Downloading tools..."); } YPlay.ShowInvalidToolsString(); } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] [HarmonyPrefix] internal static void SubmitChat_performed_Patch(HUDManager __instance, CallbackContext context) { string text = __instance.chatTextField.text; if (!string.IsNullOrEmpty(text) && text.Le
plugins\dep\YPlayUtil.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using YPlayUtil.Converters; using YPlayUtil.Helpers; using YPlayUtil.Metadata; using YPlayUtil.Options; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Bluegrams,Kerotein")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© 2020-2026 Bluegrams,Kerotein")] [assembly: AssemblyDescription("\r\n\t\tA simple .NET wrapper library for youtube-dl and yt-dlp.\r\n\r\nNote: Package versions >= 1.0 are optimized to work with yt-dlp.\r\nPackage versions 0.x retain support for the original youtube-dl.\r\n\r\nModified by Kerotein for YPlayBoombox.\r\n\t")] [assembly: AssemblyFileVersion("1.2.0.2636")] [assembly: AssemblyInformationalVersion("1.2.0+e71d54167d6fc532bfcfff26f466288cc50ccba1")] [assembly: AssemblyProduct("YPlayUtil")] [assembly: AssemblyTitle("YPlayUtil")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Bluegrams/YoutubeDLSharp")] [assembly: AssemblyVersion("1.2.0.2636")] namespace YPlayUtil { public enum DownloadState { None, PreProcessing, Downloading, PostProcessing, Error, Success } public class DownloadProgress { public DownloadState State { get; } public float Progress { get; } public string TotalDownloadSize { get; } public string DownloadSpeed { get; } public string ETA { get; } public int VideoIndex { get; } public string Data { get; } public DownloadProgress(DownloadState status, float progress = 0f, string totalDownloadSize = null, string downloadSpeed = null, string eta = null, int index = 1, string data = null) { State = status; Progress = progress; TotalDownloadSize = totalDownloadSize; DownloadSpeed = downloadSpeed; ETA = eta; VideoIndex = index; Data = data; } } public class RunResult<T> { public bool Success { get; } public string[] ErrorOutput { get; } public T Data { get; } public RunResult(bool success, string[] error, T result) { Success = success; ErrorOutput = error; Data = result; } } public static class Utils { internal class FFmpegApi { public class Root { [JsonProperty("version")] public string Version { get; set; } [JsonProperty("permalink")] public string Permalink { get; set; } [JsonProperty("bin")] public Bin Bin { get; set; } } public class Bin { [JsonProperty("windows-64")] public OsBinVersion Windows64 { get; set; } [JsonProperty("linux-64")] public OsBinVersion Linux64 { get; set; } [JsonProperty("osx-64")] public OsBinVersion Osx64 { get; set; } } public class OsBinVersion { [JsonProperty("ffmpeg")] public string Ffmpeg { get; set; } [JsonProperty("ffprobe")] public string Ffprobe { get; set; } } public enum BinaryType { [EnumMember(Value = "ffmpeg")] FFmpeg, [EnumMember(Value = "ffprobe")] FFprobe } } private static readonly Regex rgxTimestamp = new Regex("[0-9]+(?::[0-9]+)+", RegexOptions.Compiled); private static readonly Dictionary<char, string> accentChars = "ÂÃÄÀÁÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖŐØŒÙÚÛÜŰÝÞßàáâãäåæçèéêëìíîïðñòóôõöőøœùúûüűýþÿ".Zip(new string[68] { "A", "A", "A", "A", "A", "A", "AE", "C", "E", "E", "E", "E", "I", "I", "I", "I", "D", "N", "O", "O", "O", "O", "O", "O", "O", "OE", "U", "U", "U", "U", "U", "Y", "P", "ss", "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "o", "n", "o", "o", "o", "o", "o", "o", "o", "oe", "u", "u", "u", "u", "u", "y", "p", "y" }, (char c, string s) => new { Key = c, Val = s }).ToDictionary(o => o.Key, o => o.Val); public static int TimeoutSeconds { get; set; } = 300; public static string YtDlpBinaryName => GetYtDlpBinaryName(); public static string FfmpegBinaryName => GetFfmpegBinaryName(); public static string FfprobeBinaryName => GetFfprobeBinaryName(); public static string DenoBinaryName => GetDenoBinaryName(); public static string Sanitize(string s, bool restricted = false) { rgxTimestamp.Replace(s, (Match m) => m.Groups[0].Value.Replace(':', '_')); string text = string.Join("", s.Select((char c) => sanitizeChar(c, restricted))); text = text.Replace("__", "_").Trim(new char[1] { '_' }); if (restricted && text.StartsWith("-_")) { text = text.Substring(2); } if (text.StartsWith("-")) { text = "_" + text.Substring(1); } text = text.TrimStart(new char[1] { '.' }); if (string.IsNullOrWhiteSpace(text)) { text = "_"; } return text; } private static string sanitizeChar(char c, bool restricted) { if (restricted && accentChars.ContainsKey(c)) { return accentChars[c]; } if (c != '?' && c >= ' ') { switch (c) { case '\u007f': break; case '"': if (!restricted) { return "'"; } return ""; case ':': if (!restricted) { return " -"; } return "_-"; default: if (Enumerable.Contains("\\/|*<>", c)) { return "_"; } if (restricted && Enumerable.Contains("!&'()[]{}$;`^,# ", c)) { return "_"; } if (restricted && c > '\u007f') { return "_"; } return c.ToString(); } } return ""; } public static string GetFullPath(string fileName) { if (File.Exists(fileName)) { return Path.GetFullPath(fileName); } string[] array = Environment.GetEnvironmentVariable("PATH").Split(new char[1] { Path.PathSeparator }); for (int i = 0; i < array.Length; i++) { string text = Path.Combine(array[i], fileName); if (File.Exists(text)) { return text; } } return null; } public static async Task DownloadBinaries(bool skipExisting = true, string directoryPath = "", bool downloadJSRuntime = true) { if (skipExisting) { if (!File.Exists(Path.Combine(directoryPath, GetYtDlpBinaryName()))) { await DownloadYtDlp(directoryPath); } if (!File.Exists(Path.Combine(directoryPath, GetFfmpegBinaryName()))) { await DownloadFFmpeg(directoryPath); } if (!File.Exists(Path.Combine(directoryPath, GetFfprobeBinaryName()))) { await DownloadFFprobe(directoryPath); } if (downloadJSRuntime && !File.Exists(Path.Combine(directoryPath, GetDenoBinaryName()))) { await DownloadDeno(directoryPath); } } else { await DownloadYtDlp(directoryPath); await DownloadFFmpeg(directoryPath); await DownloadFFprobe(directoryPath); if (downloadJSRuntime) { await DownloadDeno(directoryPath); } } } private static string GetYtDlpBinaryName() { return OSHelper.GetOSVersion() switch { OSVersion.Windows => "yt-dlp.exe", OSVersion.OSX => "yt-dlp_macos", OSVersion.Linux => "yt-dlp", _ => throw new Exception("Your OS isn't supported"), }; } private static string GetFfmpegBinaryName() { switch (OSHelper.GetOSVersion()) { case OSVersion.Windows: return "ffmpeg.exe"; case OSVersion.OSX: case OSVersion.Linux: return "ffmpeg"; default: throw new Exception("Your OS isn't supported"); } } private static string GetFfprobeBinaryName() { switch (OSHelper.GetOSVersion()) { case OSVersion.Windows: return "ffprobe.exe"; case OSVersion.OSX: case OSVersion.Linux: return "ffprobe"; default: throw new Exception("Your OS isn't supported"); } } private static string GetDenoBinaryName() { switch (OSHelper.GetOSVersion()) { case OSVersion.Windows: return "deno.exe"; case OSVersion.OSX: case OSVersion.Linux: return "deno"; default: throw new Exception("Your OS isn't supported"); } } private static string GetYtDlpDownloadUrl() { return Path.Combine("https://github.com/yt-dlp/yt-dlp/releases/latest/download/", OSHelper.GetOSVersion() switch { OSVersion.Windows => "yt-dlp_x86.exe", OSVersion.OSX => "yt-dlp_macos", OSVersion.Linux => "yt-dlp", _ => throw new Exception("Your OS isn't supported"), }); } private static string GetDenoDownloadUrl() { return Path.Combine("https://github.com/denoland/deno/releases/latest/download/", OSHelper.GetOSVersion() switch { OSVersion.Windows => "deno-x86_64-pc-windows-msvc.zip", OSVersion.OSX => "deno-aarch64-apple-darwin.zip", OSVersion.Linux => "deno-x86_64-unknown-linux-gnu.zip", _ => throw new NotImplementedException("Your OS isn't supported"), }); } private static async Task<string> GetStringFromUrl(string url) { HttpClient client = GetHttpClient(); string result = await client.GetStringAsync(url); client?.Dispose(); return result; } private static async Task<string> GetLatestGitHubVersionFromUrl(string url) { HttpClient client = GetHttpClient(); HttpResponseMessage obj = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); client?.Dispose(); obj.EnsureSuccessStatusCode(); return obj.RequestMessage.RequestUri.Segments.LastOrDefault().TrimEnd(new char[1] { '/' }); } public static async Task<string> GetYtDlpLatestVersion() { return await GetLatestGitHubVersionFromUrl("https://github.com/yt-dlp/yt-dlp/releases/latest"); } public static async Task<string> GetDenoLatestVersion() { return await GetLatestGitHubVersionFromUrl("https://github.com/denoland/deno/releases/latest"); } public static async Task<string> GetFFmpegLatestVersion() { return JsonConvert.DeserializeObject<FFmpegApi.Root>(await GetStringFromUrl("https://ffbinaries.com/api/v1/version/latest"))?.Version; } public static async Task DownloadYtDlp(string directoryPath = "") { string ytDlpDownloadUrl = GetYtDlpDownloadUrl(); if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } string downloadLocation = Path.Combine(directoryPath, GetYtDlpBinaryName()); File.WriteAllBytes(downloadLocation, await DownloadFileBytesAsync(ytDlpDownloadUrl)); SetUnixExecPerms(downloadLocation); } public static async Task DownloadDeno(string directoryPath = "") { string denoDownloadUrl = GetDenoDownloadUrl(); if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } byte[] buffer = await DownloadFileBytesAsync(denoDownloadUrl); string unixExecPerms = string.Empty; using (MemoryStream stream = new MemoryStream(buffer)) { using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read); if (zipArchive.Entries.Count > 0) { unixExecPerms = Path.Combine(directoryPath, zipArchive.Entries[0].FullName); zipArchive.Entries[0].ExtractToFile(Path.Combine(directoryPath, zipArchive.Entries[0].FullName), overwrite: true); } } SetUnixExecPerms(unixExecPerms); } public static async Task DownloadFFmpeg(string directoryPath = "") { await FFDownloader(directoryPath); } public static async Task DownloadFFprobe(string directoryPath = "") { await FFDownloader(directoryPath, FFmpegApi.BinaryType.FFprobe); } private static void SetUnixExecPerms(string filename) { if (OSHelper.IsWindows) { return; } throw new PlatformNotSupportedException("Setting Unix permissions is not supported on this platform."); } private static HttpClient GetHttpClient() { HttpClient httpClient = null; if (httpClient == null) { httpClient = new HttpClient(); httpClient.Timeout = TimeSpan.FromSeconds(TimeoutSeconds); } return httpClient; } private static async Task FFDownloader(string directoryPath = "", FFmpegApi.BinaryType binary = FFmpegApi.BinaryType.FFmpeg) { HttpClient client = GetHttpClient(); if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } FFmpegApi.Root root = JsonConvert.DeserializeObject<FFmpegApi.Root>(await GetStringFromUrl("https://ffbinaries.com/api/v1/version/latest")); FFmpegApi.OsBinVersion osBinVersion = OSHelper.GetOSVersion() switch { OSVersion.Windows => root?.Bin.Windows64, OSVersion.OSX => root?.Bin.Osx64, OSVersion.Linux => root?.Bin.Linux64, _ => throw new NotImplementedException("Your OS isn't supported"), }; byte[] buffer = await DownloadFileBytesAsync((binary == FFmpegApi.BinaryType.FFmpeg) ? osBinVersion.Ffmpeg : osBinVersion.Ffprobe); string unixExecPerms = string.Empty; using (MemoryStream stream = new MemoryStream(buffer)) { using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read); if (zipArchive.Entries.Count > 0) { unixExecPerms = Path.Combine(directoryPath, zipArchive.Entries[0].FullName); zipArchive.Entries[0].ExtractToFile(Path.Combine(directoryPath, zipArchive.Entries[0].FullName), overwrite: true); } } SetUnixExecPerms(unixExecPerms); client?.Dispose(); } private static async Task<byte[]> DownloadFileBytesAsync(string uri) { if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri _)) { throw new InvalidOperationException("URI is invalid."); } HttpClient client = GetHttpClient(); byte[] result2 = await client.GetByteArrayAsync(uri); client?.Dispose(); return result2; } public static void EnsureSuccess<T>(this RunResult<T> runResult) { if (!runResult.Success) { throw new Exception("Download failed:\n" + string.Join("\n", runResult.ErrorOutput)); } } } public class YoutubeDL { private static readonly Regex rgxFile = new Regex("^outfile:\\s\\\"?(.*)\\\"?", RegexOptions.Compiled); private static Regex rgxFilePostProc = new Regex("\\[download\\] Destination: [a-zA-Z]:\\\\\\S+\\.\\S{3,}", RegexOptions.Compiled); protected ProcessRunner runner; public string YoutubeDLPath { get; set; } = Utils.YtDlpBinaryName; public string FFmpegPath { get; set; } = Utils.FfmpegBinaryName; public string OutputFolder { get; set; } = Environment.CurrentDirectory; public string OutputFileTemplate { get; set; } = "%(title)s [%(id)s].%(ext)s"; public bool RestrictFilenames { get; set; } public bool OverwriteFiles { get; set; } = true; public bool IgnoreDownloadErrors { get; set; } = true; public string PythonInterpreterPath { get; set; } public string Version => FileVersionInfo.GetVersionInfo(Utils.GetFullPath(YoutubeDLPath)).FileVersion; public YoutubeDL(byte maxNumberOfProcesses = 4) { runner = new ProcessRunner(maxNumberOfProcesses); } public async Task SetMaxNumberOfProcesses(byte count) { await runner.SetTotalCount(count); } public async Task<RunResult<string[]>> RunWithOptions(string[] urls, OptionSet options, CancellationToken ct) { List<string> output = new List<string>(); YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { output.Add(e.Data); }; var (num, error) = await runner.RunThrottled(youtubeDLProcess, urls, options, ct); return new RunResult<string[]>(num == 0, error, output.ToArray()); } public async Task<RunResult<string>> RunWithOptions(string url, OptionSet options, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, bool showArgs = true) { string outFile = string.Empty; YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); if (showArgs) { output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, options) + "\n"); } else { output?.Report("Starting Download: " + url); } youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { Match match = rgxFilePostProc.Match(e.Data); if (match.Success) { outFile = match.Groups[0].ToString().Replace("[download] Destination:", "").Replace(" ", ""); progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, outFile)); } output?.Report(e.Data); }; var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, options, ct, progress); return new RunResult<string>(num == 0, error, outFile); } public async Task<string> RunUpdate() { string output = string.Empty; YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { output = e.Data; }; await youtubeDLProcess.RunAsync(null, new OptionSet { Update = true }); return output; } public async Task<RunResult<VideoData>> RunVideoDataFetch(string url, CancellationToken ct = default(CancellationToken), bool flat = true, bool fetchComments = false, OptionSet overrideOptions = null) { OptionSet optionSet = GetDownloadOptions(); optionSet.DumpSingleJson = true; optionSet.FlatPlaylist = flat; optionSet.WriteComments = fetchComments; if (overrideOptions != null) { optionSet = optionSet.OverrideOptions(overrideOptions); } VideoData videoData = null; YoutubeDLProcess process = CreateYoutubeDLProcess(); process.OutputReceived += delegate(object o, DataReceivedEventArgs e) { try { videoData = JsonConvert.DeserializeObject<VideoData>(e.Data); } catch (JsonSerializationException) { process.RedirectToError(e); } }; var (num, error) = await runner.RunThrottled(process, new string[1] { url }, optionSet, ct); return new RunResult<VideoData>(num == 0, error, videoData); } public async Task<RunResult<string>> RunVideoDownload(string url, string format = "bestvideo+bestaudio/best", DownloadMergeFormat mergeFormat = DownloadMergeFormat.Unspecified, VideoRecodeFormat recodeFormat = VideoRecodeFormat.None, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null) { OptionSet optionSet = GetDownloadOptions(); optionSet.Format = format; optionSet.MergeOutputFormat = mergeFormat; optionSet.RecodeVideo = recodeFormat; if (overrideOptions != null) { optionSet = optionSet.OverrideOptions(overrideOptions); } string outputFile = string.Empty; YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n"); youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { Match match = rgxFile.Match(e.Data); if (match.Success) { outputFile = match.Groups[1].ToString().Trim(new char[1] { '"' }); progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, outputFile)); } output?.Report(e.Data); }; var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress); return new RunResult<string>(num == 0, error, outputFile); } public async Task<RunResult<string[]>> RunVideoPlaylistDownload(string url, int? start = 1, int? end = null, int[] items = null, string format = "bestvideo+bestaudio/best", VideoRecodeFormat recodeFormat = VideoRecodeFormat.None, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null) { OptionSet optionSet = GetDownloadOptions(); optionSet.NoPlaylist = false; optionSet.PlaylistStart = start; optionSet.PlaylistEnd = end; if (items != null) { optionSet.PlaylistItems = string.Join(",", items); } optionSet.Format = format; optionSet.RecodeVideo = recodeFormat; if (overrideOptions != null) { optionSet = optionSet.OverrideOptions(overrideOptions); } List<string> outputFiles = new List<string>(); YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n"); youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { Match match = rgxFile.Match(e.Data); if (match.Success) { string text = match.Groups[1].ToString().Trim(new char[1] { '"' }); outputFiles.Add(text); progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, text)); } output?.Report(e.Data); }; var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress); return new RunResult<string[]>(num == 0, error, outputFiles.ToArray()); } public async Task<RunResult<string>> RunAudioDownload(string url, AudioConversionFormat format = AudioConversionFormat.Best, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null) { OptionSet optionSet = GetDownloadOptions(); optionSet.Format = "bestaudio/best"; optionSet.ExtractAudio = true; optionSet.AudioFormat = format; if (overrideOptions != null) { optionSet = optionSet.OverrideOptions(overrideOptions); } string outputFile = string.Empty; new List<string>(); YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n"); youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { Match match = rgxFile.Match(e.Data); if (match.Success) { outputFile = match.Groups[1].ToString().Trim(new char[1] { '"' }); progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, outputFile)); } output?.Report(e.Data); }; var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress); return new RunResult<string>(num == 0, error, outputFile); } public async Task<RunResult<string[]>> RunAudioPlaylistDownload(string url, int? start = 1, int? end = null, int[] items = null, AudioConversionFormat format = AudioConversionFormat.Best, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null) { List<string> outputFiles = new List<string>(); OptionSet optionSet = GetDownloadOptions(); optionSet.NoPlaylist = false; optionSet.PlaylistStart = start; optionSet.PlaylistEnd = end; if (items != null) { optionSet.PlaylistItems = string.Join(",", items); } optionSet.Format = "bestaudio/best"; optionSet.ExtractAudio = true; optionSet.AudioFormat = format; if (overrideOptions != null) { optionSet = optionSet.OverrideOptions(overrideOptions); } YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess(); output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n"); youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e) { Match match = rgxFile.Match(e.Data); if (match.Success) { string text = match.Groups[1].ToString().Trim(new char[1] { '"' }); outputFiles.Add(text); progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, text)); } output?.Report(e.Data); }; var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress); return new RunResult<string[]>(num == 0, error, outputFiles.ToArray()); } protected virtual OptionSet GetDownloadOptions() { return new OptionSet { IgnoreErrors = IgnoreDownloadErrors, IgnoreConfig = true, NoPlaylist = true, Downloader = "m3u8:native", DownloaderArgs = "ffmpeg:-nostats -loglevel 0", Output = Path.Combine(OutputFolder, OutputFileTemplate), RestrictFilenames = RestrictFilenames, ForceOverwrites = OverwriteFiles, NoOverwrites = !OverwriteFiles, NoPart = true, FfmpegLocation = Utils.GetFullPath(FFmpegPath), Progress = true, Print = "after_move:outfile: %(filepath)s" }; } private YoutubeDLProcess CreateYoutubeDLProcess() { return new YoutubeDLProcess(YoutubeDLPath) { PythonPath = PythonInterpreterPath }; } } public class YoutubeDLProcess { private static readonly Regex rgxPlaylist = new Regex("Downloading video (\\d+) of (\\d+)", RegexOptions.Compiled); private static readonly Regex rgxProgress = new Regex("\\[download\\]\\s+(?:(?<percent>[\\d\\.]+)%(?:\\s+of\\s+\\~?\\s*(?<total>[\\d\\.\\w]+))?\\s+at\\s+(?:(?<speed>[\\d\\.\\w]+\\/s)|[\\w\\s]+)\\s+ETA\\s(?<eta>[\\d\\:]+))?", RegexOptions.Compiled); private static readonly Regex rgxPost = new Regex("\\[(\\w+)\\]\\s+", RegexOptions.Compiled); public string PythonPath { get; set; } public string ExecutablePath { get; set; } public event EventHandler<DataReceivedEventArgs> OutputReceived; public event EventHandler<DataReceivedEventArgs> ErrorReceived; public YoutubeDLProcess(string executablePath = "yt-dlp.exe") { ExecutablePath = executablePath; } internal string ConvertToArgs(string[] urls, OptionSet options) { return options.ToString() + " -- " + ((urls != null) ? string.Join(" ", urls.Select((string s) => "\"" + s + "\"")) : string.Empty); } internal void RedirectToError(DataReceivedEventArgs e) { this.ErrorReceived?.Invoke(this, e); } public async Task<int> RunAsync(string[] urls, OptionSet options) { return await RunAsync(urls, options, CancellationToken.None); } public async Task<int> RunAsync(string[] urls, OptionSet options, CancellationToken ct, IProgress<DownloadProgress> progress = null) { TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); Process process = new Process(); ProcessStartInfo processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8 }; if (!string.IsNullOrEmpty(PythonPath)) { processStartInfo.FileName = PythonPath; processStartInfo.Arguments = "\"" + ExecutablePath + "\" " + ConvertToArgs(urls, options); } else { processStartInfo.FileName = ExecutablePath; processStartInfo.Arguments = ConvertToArgs(urls, options); } process.EnableRaisingEvents = true; process.StartInfo = processStartInfo; TaskCompletionSource<bool> tcsOut = new TaskCompletionSource<bool>(); bool isDownloading = false; process.OutputDataReceived += delegate(object o, DataReceivedEventArgs e) { if (e.Data == null) { tcsOut.SetResult(result: true); } else { Match match; if ((match = rgxProgress.Match(e.Data)).Success) { if (match.Groups.Count > 1 && match.Groups[1].Length > 0) { float progress2 = float.Parse(match.Groups[1].ToString(), CultureInfo.InvariantCulture) / 100f; Group group = match.Groups["total"]; string totalDownloadSize = (group.Success ? group.Value : null); Group group2 = match.Groups["speed"]; string downloadSpeed = (group2.Success ? group2.Value : null); Group group3 = match.Groups["eta"]; string eta = (group3.Success ? group3.Value : null); progress?.Report(new DownloadProgress(DownloadState.Downloading, progress2, totalDownloadSize, downloadSpeed, eta)); } else { progress?.Report(new DownloadProgress(DownloadState.Downloading)); } isDownloading = true; } else if ((match = rgxPlaylist.Match(e.Data)).Success) { int index = int.Parse(match.Groups[1].Value); progress?.Report(new DownloadProgress(DownloadState.PreProcessing, 0f, null, null, null, index)); isDownloading = false; } else if (isDownloading && (match = rgxPost.Match(e.Data)).Success) { progress?.Report(new DownloadProgress(DownloadState.PostProcessing, 1f)); isDownloading = false; } this.OutputReceived?.Invoke(this, e); } }; TaskCompletionSource<bool> tcsError = new TaskCompletionSource<bool>(); process.ErrorDataReceived += delegate(object o, DataReceivedEventArgs e) { if (e.Data == null) { tcsError.SetResult(result: true); } else { progress?.Report(new DownloadProgress(DownloadState.Error, 0f, null, null, null, 1, e.Data)); this.ErrorReceived?.Invoke(this, e); } }; process.Exited += async delegate { await tcsOut.Task; await tcsError.Task; tcs.TrySetResult(process.ExitCode); process.Dispose(); }; ct.Register(delegate { if (!tcs.Task.IsCompleted) { tcs.TrySetCanceled(); } try { if (!process.HasExited) { process.KillTree(); } } catch { } }); if (!(await Task.Run(() => process.Start()))) { tcs.TrySetException(new InvalidOperationException("Failed to start yt-dlp process.")); } process.BeginOutputReadLine(); process.BeginErrorReadLine(); progress?.Report(new DownloadProgress(DownloadState.PreProcessing)); return await tcs.Task; } } } namespace YPlayUtil.Options { public enum DownloadMergeFormat { Unspecified, Mp4, Mkv, Ogg, Webm, Flv } public enum AudioConversionFormat { Best, Aac, Flac, Mp3, M4a, Opus, Vorbis, Wav } public enum VideoRecodeFormat { None, Mp4, Mkv, Ogg, Webm, Flv, Avi } public interface IOption { string DefaultOptionString { get; } string[] OptionStrings { get; } bool IsSet { get; } bool IsCustom { get; } void SetFromString(string s); IEnumerable<string> ToStringCollection(); } public class MultiOption<T> : IOption { private MultiValue<T> value; public string DefaultOptionString => OptionStrings.Last(); public string[] OptionStrings { get; } public bool IsSet { get; private set; } public bool IsCustom { get; } public MultiValue<T> Value { get { return value; } set { IsSet = !object.Equals(value, default(T)); this.value = value; } } public MultiOption(params string[] optionStrings) { OptionStrings = optionStrings; IsSet = false; } public MultiOption(bool isCustom, params string[] optionStrings) { OptionStrings = optionStrings; IsSet = false; IsCustom = isCustom; } public void SetFromString(string s) { string[] array = s.Split(new char[1] { ' ' }); string text = s.Substring(array[0].Length).Trim(); if (typeof(T) != typeof(StringVals)) { text = text.Trim(new char[1] { '"' }); } if (!OptionStrings.Contains(array[0])) { throw new ArgumentException("Given string does not match required format."); } T val = Utils.OptionValueFromString<T>(text); if (!IsSet) { Value = val; } else { Value.Values.Add(val); } } public override string ToString() { return string.Join(" ", ToStringCollection()); } public IEnumerable<string> ToStringCollection() { if (!IsSet) { return new string[1] { "" }; } List<string> list = new List<string>(); foreach (T value in Value.Values) { list.Add(DefaultOptionString + Utils.OptionValueToString(value)); } return list; } } public class MultiValue<T> { private readonly List<T> values; public List<T> Values => values; public MultiValue(params T[] values) { this.values = values.ToList(); } public static implicit operator MultiValue<T>(T value) { return new MultiValue<T>(value); } public static implicit operator MultiValue<T>(T[] values) { return new MultiValue<T>(values); } public static explicit operator T(MultiValue<T> value) { if (value.Values.Count == 1) { return value.Values[0]; } throw new InvalidCastException($"Cannot cast sequence of values to {typeof(T)}."); } public static explicit operator T[](MultiValue<T> value) { return value.Values.ToArray(); } } public class Option<T> : IOption { private T value; public string DefaultOptionString => OptionStrings.First(); public string[] OptionStrings { get; } public bool IsSet { get; private set; } public T Value { get { return value; } set { IsSet = !object.Equals(value, default(T)); this.value = value; } } public bool IsCustom { get; } public Option(params string[] optionStrings) { OptionStrings = optionStrings; IsSet = false; } public Option(bool isCustom, params string[] optionStrings) { OptionStrings = optionStrings; IsSet = false; IsCustom = isCustom; } public void SetFromString(string s) { string[] array = s.Split(new char[1] { ' ' }); string text = s.Substring(array[0].Length).Trim(); if (typeof(T) != typeof(StringVals)) { text = text.Trim(new char[1] { '"' }); } if (!OptionStrings.Contains(array[0])) { throw new ArgumentException("Given string does not match required format."); } Value = Utils.OptionValueFromString<T>(text); } public override string ToString() { if (!IsSet) { return string.Empty; } string text = Utils.OptionValueToString(Value); return DefaultOptionString + text; } public IEnumerable<string> ToStringCollection() { return new string[1] { ToString() }; } } internal class OptionComparer : IEqualityComparer<IOption> { public bool Equals(IOption x, IOption y) { if (x != null) { if (y != null) { return x.ToString().Equals(y.ToString()); } return false; } return y == null; } public int GetHashCode(IOption obj) { return obj.ToString().GetHashCode(); } } public class OptionSet : ICloneable { [CompilerGenerated] private sealed class <>c__DisplayClass64_0 { public string flag; internal bool <GetOptions>b__0(IOption o) { return o.OptionStrings.Contains(flag); } } [CompilerGenerated] private sealed class <GetOptions>d__64 : IEnumerable<IOption>, IEnumerable, IEnumerator<IOption>, IEnumerator, IDisposable { private int <>1__state; private IOption <>2__current; private int <>l__initialThreadId; private IEnumerable<IOption> options; public IEnumerable<IOption> <>3__options; private IEnumerable<string> lines; public IEnumerable<string> <>3__lines; private IEnumerable<IOption> <knownOptions>5__2; private IEnumerator<string> <>7__wrap2; IOption IEnumerator<IOption>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetOptions>d__64(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <knownOptions>5__2 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <knownOptions>5__2 = options.ToList(); <>7__wrap2 = lines.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap2.MoveNext()) { string current = <>7__wrap2.Current; <>c__DisplayClass64_0 CS$<>8__locals0 = new <>c__DisplayClass64_0(); string text = current.Trim(); if (!text.StartsWith("#") && !string.IsNullOrWhiteSpace(text)) { string[] array = text.Split(new char[1] { ' ' }); CS$<>8__locals0.flag = array[0]; IOption option = <knownOptions>5__2.FirstOrDefault((IOption o) => o.OptionStrings.Contains(CS$<>8__locals0.flag)); IOption option3; if (array.Length <= 1) { IOption option2 = new Option<bool>(true, CS$<>8__locals0.flag); option3 = option2; } else { IOption option2 = new Option<string>(true, CS$<>8__locals0.flag); option3 = option2; } IOption option4 = option3; IOption option5 = option ?? option4; option5.SetFromString(text); <>2__current = option5; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap2 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<IOption> IEnumerable<IOption>.GetEnumerator() { <GetOptions>d__64 <GetOptions>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetOptions>d__ = this; } else { <GetOptions>d__ = new <GetOptions>d__64(0); } <GetOptions>d__.lines = <>3__lines; <GetOptions>d__.options = <>3__options; return <GetOptions>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<IOption>)this).GetEnumerator(); } } private Option<string> username = new Option<string>("-u", "--username"); private Option<string> password = new Option<string>("-p", "--password"); private Option<string> twoFactor = new Option<string>("-2", "--twofactor"); private Option<bool> netrc = new Option<bool>("-n", "--netrc"); private Option<string> netrcLocation = new Option<string>("--netrc-location"); private Option<string> netrcCmd = new Option<string>("--netrc-cmd"); private Option<string> videoPassword = new Option<string>("--video-password"); private Option<string> apMso = new Option<string>("--ap-mso"); private Option<string> apUsername = new Option<string>("--ap-username"); private Option<string> apPassword = new Option<string>("--ap-password"); private Option<bool> apListMso = new Option<bool>("--ap-list-mso"); private Option<string> clientCertificate = new Option<string>("--client-certificate"); private Option<string> clientCertificateKey = new Option<string>("--client-certificate-key"); private Option<string> clientCertificatePassword = new Option<string>("--client-certificate-password"); private static readonly OptionComparer Comparer = new OptionComparer(); public static readonly OptionSet Default = new OptionSet(); private Option<bool> getDescription = new Option<bool>("--get-description"); private Option<bool> getDuration = new Option<bool>("--get-duration"); private Option<bool> getFilename = new Option<bool>("--get-filename"); private Option<bool> getFormat = new Option<bool>("--get-format"); private Option<bool> getId = new Option<bool>("--get-id"); private Option<bool> getThumbnail = new Option<bool>("--get-thumbnail"); private Option<bool> getTitle = new Option<bool>("-e", "--get-title"); private Option<bool> getUrl = new Option<bool>("-g", "--get-url"); private Option<string> matchTitle = new Option<string>("--match-title"); private Option<string> rejectTitle = new Option<string>("--reject-title"); private Option<long?> minViews = new Option<long?>("--min-views"); private Option<long?> maxViews = new Option<long?>("--max-views"); private Option<bool> breakOnReject = new Option<bool>("--break-on-reject"); private Option<string> userAgent = new Option<string>("--user-agent"); private Option<string> referer = new Option<string>("--referer"); private Option<int?> playlistStart = new Option<int?>("--playlist-start"); private Option<int?> playlistEnd = new Option<int?>("--playlist-end"); private Option<bool> playlistReverse = new Option<bool>("--playlist-reverse"); private Option<bool> noColors = new Option<bool>("--no-colors"); private Option<bool> forceGenericExtractor = new Option<bool>("--force-generic-extractor"); private Option<string> execBeforeDownload = new Option<string>("--exec-before-download"); private Option<bool> noExecBeforeDownload = new Option<bool>("--no-exec-before-download"); private Option<bool> allFormats = new Option<bool>("--all-formats"); private Option<bool> allSubs = new Option<bool>("--all-subs"); private Option<bool> printJson = new Option<bool>("--print-json"); private Option<string> autonumberSize = new Option<string>("--autonumber-size"); private Option<int?> autonumberStart = new Option<int?>("--autonumber-start"); private Option<bool> id = new Option<bool>("--id"); private Option<string> metadataFromTitle = new Option<string>("--metadata-from-title"); private Option<bool> hlsPreferNative = new Option<bool>("--hls-prefer-native"); private Option<bool> hlsPreferFfmpeg = new Option<bool>("--hls-prefer-ffmpeg"); private Option<bool> listFormatsOld = new Option<bool>("--list-formats-old", "--no-list-formats-as-table"); private Option<bool> listFormatsAsTable = new Option<bool>("--list-formats-as-table", "--no-list-formats-old"); private Option<bool> youtubeSkipDashManifest = new Option<bool>("--youtube-skip-dash-manifest", "--no-youtube-include-dash-manifest"); private Option<bool> youtubeSkipHlsManifest = new Option<bool>("--youtube-skip-hls-manifest", "--no-youtube-include-hls-manifest"); private Option<bool> geoBypass = new Option<bool>("--geo-bypass"); private Option<bool> noGeoBypass = new Option<bool>("--no-geo-bypass"); private Option<string> geoBypassCountry = new Option<string>("--geo-bypass-country"); private Option<string> geoBypassIpBlock = new Option<string>("--geo-bypass-ip-block"); private Option<int?> concurrentFragments = new Option<int?>("-N", "--concurrent-fragments"); private Option<long?> limitRate = new Option<long?>("-r", "--limit-rate"); private Option<long?> throttledRate = new Option<long?>("--throttled-rate"); private Option<int?> retries = new Option<int?>("-R", "--retries"); private Option<int?> fileAccessRetries = new Option<int?>("--file-access-retries"); private Option<int?> fragmentRetries = new Option<int?>("--fragment-retries"); private MultiOption<string> retrySleep = new MultiOption<string>("--retry-sleep"); private Option<bool> skipUnavailableFragments = new Option<bool>("--skip-unavailable-fragments", "--no-abort-on-unavailable-fragments"); private Option<bool> abortOnUnavailableFragments = new Option<bool>("--abort-on-unavailable-fragments", "--no-skip-unavailable-fragments"); private Option<bool> keepFragments = new Option<bool>("--keep-fragments"); private Option<bool> noKeepFragments = new Option<bool>("--no-keep-fragments"); private Option<long?> bufferSize = new Option<long?>("--buffer-size"); private Option<bool> resizeBuffer = new Option<bool>("--resize-buffer"); private Option<bool> noResizeBuffer = new Option<bool>("--no-resize-buffer"); private Option<long?> httpChunkSize = new Option<long?>("--http-chunk-size"); private Option<bool> playlistRandom = new Option<bool>("--playlist-random"); private Option<bool> lazyPlaylist = new Option<bool>("--lazy-playlist"); private Option<bool> noLazyPlaylist = new Option<bool>("--no-lazy-playlist"); private Option<bool> hlsUseMpegts = new Option<bool>("--hls-use-mpegts"); private Option<bool> noHlsUseMpegts = new Option<bool>("--no-hls-use-mpegts"); private MultiOption<string> downloadSections = new MultiOption<string>("--download-sections"); private MultiOption<string> downloader = new MultiOption<string>("--downloader", "--external-downloader"); private MultiOption<string> downloaderArgs = new MultiOption<string>("--downloader-args", "--external-downloader-args"); private Option<int?> extractorRetries = new Option<int?>("--extractor-retries"); private Option<bool> allowDynamicMpd = new Option<bool>("--allow-dynamic-mpd", "--no-ignore-dynamic-mpd"); private Option<bool> ignoreDynamicMpd = new Option<bool>("--ignore-dynamic-mpd", "--no-allow-dynamic-mpd"); private Option<bool> hlsSplitDiscontinuity = new Option<bool>("--hls-split-discontinuity"); private Option<bool> noHlsSplitDiscontinuity = new Option<bool>("--no-hls-split-discontinuity"); private MultiOption<string> extractorArgs = new MultiOption<string>("--extractor-args"); private Option<string> batchFile = new Option<string>("-a", "--batch-file"); private Option<bool> noBatchFile = new Option<bool>("--no-batch-file"); private MultiOption<string> paths = new MultiOption<string>("-P", "--paths"); private Option<string> output = new Option<string>("-o", "--output"); private Option<string> outputNaPlaceholder = new Option<string>("--output-na-placeholder"); private Option<bool> restrictFilenames = new Option<bool>("--restrict-filenames"); private Option<bool> noRestrictFilenames = new Option<bool>("--no-restrict-filenames"); private Option<bool> windowsFilenames = new Option<bool>("--windows-filenames"); private Option<bool> noWindowsFilenames = new Option<bool>("--no-windows-filenames"); private Option<int?> trimFilenames = new Option<int?>("--trim-filenames"); private Option<bool> noOverwrites = new Option<bool>("-w", "--no-overwrites"); private Option<bool> forceOverwrites = new Option<bool>("--force-overwrites"); private Option<bool> noForceOverwrites = new Option<bool>("--no-force-overwrites"); private Option<bool> doContinue = new Option<bool>("-c", "--continue"); private Option<bool> noContinue = new Option<bool>("--no-continue"); private Option<bool> part = new Option<bool>("--part"); private Option<bool> noPart = new Option<bool>("--no-part"); private Option<bool> mtime = new Option<bool>("--mtime"); private Option<bool> noMtime = new Option<bool>("--no-mtime"); private Option<bool> writeDescription = new Option<bool>("--write-description"); private Option<bool> noWriteDescription = new Option<bool>("--no-write-description"); private Option<bool> writeInfoJson = new Option<bool>("--write-info-json"); private Option<bool> noWriteInfoJson = new Option<bool>("--no-write-info-json"); private Option<bool> writePlaylistMetafiles = new Option<bool>("--write-playlist-metafiles"); private Option<bool> noWritePlaylistMetafiles = new Option<bool>("--no-write-playlist-metafiles"); private Option<bool> cleanInfoJson = new Option<bool>("--clean-info-json"); private Option<bool> noCleanInfoJson = new Option<bool>("--no-clean-info-json"); private Option<bool> writeComments = new Option<bool>("--write-comments", "--get-comments"); private Option<bool> noWriteComments = new Option<bool>("--no-write-comments", "--no-get-comments"); private Option<string> loadInfoJson = new Option<string>("--load-info-json"); private Option<string> cookies = new Option<string>("--cookies"); private Option<bool> noCookies = new Option<bool>("--no-cookies"); private Option<string> cookiesFromBrowser = new Option<string>("--cookies-from-browser"); private Option<bool> noCookiesFromBrowser = new Option<bool>("--no-cookies-from-browser"); private Option<string> cacheDir = new Option<string>("--cache-dir"); private Option<bool> noCacheDir = new Option<bool>("--no-cache-dir"); private Option<bool> removeCacheDir = new Option<bool>("--rm-cache-dir"); private Option<bool> help = new Option<bool>("-h", "--help"); private Option<bool> version = new Option<bool>("--version"); private Option<bool> update = new Option<bool>("-U", "--update"); private Option<bool> noUpdate = new Option<bool>("--no-update"); private Option<string> updateTo = new Option<string>("--update-to"); private Option<bool> ignoreErrors = new Option<bool>("-i", "--ignore-errors"); private Option<bool> noAbortOnError = new Option<bool>("--no-abort-on-error"); private Option<bool> abortOnError = new Option<bool>("--abort-on-error", "--no-ignore-errors"); private Option<bool> listExtractors = new Option<bool>("--list-extractors"); private Option<bool> extractorDescriptions = new Option<bool>("--extractor-descriptions"); private Option<string> useExtractors = new Option<string>("--use-extractors", "--ies"); private Option<string> defaultSearch = new Option<string>("--default-search"); private Option<bool> ignoreConfig = new Option<bool>("--ignore-config", "--no-config"); private Option<bool> noConfigLocations = new Option<bool>("--no-config-locations"); private MultiOption<string> configLocations = new MultiOption<string>("--config-locations"); private MultiOption<string> pluginDirs = new MultiOption<string>("--plugin-dirs"); private Option<bool> noPluginDirs = new Option<bool>("--no-plugin-dirs"); private MultiOption<string> jsRuntimes = new MultiOption<string>("--js-runtimes"); private Option<bool> noJsRuntimes = new Option<bool>("--no-js-runtimes"); private MultiOption<string> remoteComponents = new MultiOption<string>("--remote-components"); private Option<bool> noRemoteComponents = new Option<bool>("--no-remote-components"); private Option<bool> flatPlaylist = new Option<bool>("--flat-playlist"); private Option<bool> noFlatPlaylist = new Option<bool>("--no-flat-playlist"); private Option<bool> liveFromStart = new Option<bool>("--live-from-start"); private Option<bool> noLiveFromStart = new Option<bool>("--no-live-from-start"); private Option<string> waitForVideo = new Option<string>("--wait-for-video"); private Option<bool> noWaitForVideo = new Option<bool>("--no-wait-for-video"); private Option<bool> markWatched = new Option<bool>("--mark-watched"); private Option<bool> noMarkWatched = new Option<bool>("--no-mark-watched"); private MultiOption<string> color = new MultiOption<string>("--color"); private Option<string> compatOptions = new Option<string>("--compat-options"); private MultiOption<StringVals> alias = new MultiOption<StringVals>("--alias"); private MultiOption<string> presetAlias = new MultiOption<string>("-t", "--preset-alias"); private Option<string> geoVerificationProxy = new Option<string>("--geo-verification-proxy"); private Option<string> xff = new Option<string>("--xff"); private Option<bool> writeLink = new Option<bool>("--write-link"); private Option<bool> writeUrlLink = new Option<bool>("--write-url-link"); private Option<bool> writeWeblocLink = new Option<bool>("--write-webloc-link"); private Option<bool> writeDesktopLink = new Option<bool>("--write-desktop-link"); private Option<string> proxy = new Option<string>("--proxy"); private Option<int?> socketTimeout = new Option<int?>("--socket-timeout"); private Option<string> sourceAddress = new Option<string>("--source-address"); private Option<string> impersonate = new Option<string>("--impersonate"); private Option<bool> listImpersonateTargets = new Option<bool>("--list-impersonate-targets"); private Option<bool> forceIPv4 = new Option<bool>("-4", "--force-ipv4"); private Option<bool> forceIPv6 = new Option<bool>("-6", "--force-ipv6"); private Option<bool> enableFileUrls = new Option<bool>("--enable-file-urls"); private Option<bool> extractAudio = new Option<bool>("-x", "--extract-audio"); private Option<AudioConversionFormat> audioFormat = new Option<AudioConversionFormat>("--audio-format"); private Option<byte?> audioQuality = new Option<byte?>("--audio-quality"); private Option<string> remuxVideo = new Option<string>("--remux-video"); private Option<VideoRecodeFormat> recodeVideo = new Option<VideoRecodeFormat>("--recode-video"); private MultiOption<string> postprocessorArgs = new MultiOption<string>("--postprocessor-args", "--ppa"); private Option<bool> keepVideo = new Option<bool>("-k", "--keep-video"); private Option<bool> noKeepVideo = new Option<bool>("--no-keep-video"); private Option<bool> postOverwrites = new Option<bool>("--post-overwrites"); private Option<bool> noPostOverwrites = new Option<bool>("--no-post-overwrites"); private Option<bool> embedSubs = new Option<bool>("--embed-subs"); private Option<bool> noEmbedSubs = new Option<bool>("--no-embed-subs"); private Option<bool> embedThumbnail = new Option<bool>("--embed-thumbnail"); private Option<bool> noEmbedThumbnail = new Option<bool>("--no-embed-thumbnail"); private Option<bool> embedMetadata = new Option<bool>("--embed-metadata", "--add-metadata"); private Option<bool> noEmbedMetadata = new Option<bool>("--no-embed-metadata", "--no-add-metadata"); private Option<bool> embedChapters = new Option<bool>("--embed-chapters", "--add-chapters"); private Option<bool> noEmbedChapters = new Option<bool>("--no-embed-chapters", "--no-add-chapters"); private Option<bool> embedInfoJson = new Option<bool>("--embed-info-json"); private Option<bool> noEmbedInfoJson = new Option<bool>("--no-embed-info-json"); private Option<string> parseMetadata = new Option<string>("--parse-metadata"); private MultiOption<StringVals> replaceInMetadata = new MultiOption<StringVals>("--replace-in-metadata"); private Option<bool> xattrs = new Option<bool>("--xattrs"); private Option<string> concatPlaylist = new Option<string>("--concat-playlist"); private Option<string> fixup = new Option<string>("--fixup"); private Option<string> ffmpegLocation = new Option<string>("--ffmpeg-location"); private MultiOption<string> exec = new MultiOption<string>("--exec"); private Option<bool> noExec = new Option<bool>("--no-exec"); private Option<string> convertSubs = new Option<string>("--convert-subs"); private Option<string> convertThumbnails = new Option<string>("--convert-thumbnails"); private Option<bool> splitChapters = new Option<bool>("--split-chapters"); private Option<bool> noSplitChapters = new Option<bool>("--no-split-chapters"); private MultiOption<string> removeChapters = new MultiOption<string>("--remove-chapters"); private Option<bool> noRemoveChapters = new Option<bool>("--no-remove-chapters"); private Option<bool> forceKeyframesAtCuts = new Option<bool>("--force-keyframes-at-cuts"); private Option<bool> noForceKeyframesAtCuts = new Option<bool>("--no-force-keyframes-at-cuts"); private MultiOption<string> usePostprocessor = new MultiOption<string>("--use-postprocessor"); private Option<string> sponsorblockMark = new Option<string>("--sponsorblock-mark"); private Option<string> sponsorblockRemove = new Option<string>("--sponsorblock-remove"); private Option<string> sponsorblockChapterTitle = new Option<string>("--sponsorblock-chapter-title"); private Option<bool> noSponsorblock = new Option<bool>("--no-sponsorblock"); private Option<string> sponsorblockApi = new Option<string>("--sponsorblock-api"); private Option<bool> writeSubs = new Option<bool>("--write-subs"); private Option<bool> noWriteSubs = new Option<bool>("--no-write-subs"); private Option<bool> writeAutoSubs = new Option<bool>("--write-auto-subs", "--write-automatic-subs"); private Option<bool> noWriteAutoSubs = new Option<bool>("--no-write-auto-subs", "--no-write-automatic-subs"); private Option<bool> listSubs = new Option<bool>("--list-subs"); private Option<string> subFormat = new Option<string>("--sub-format"); private Option<string> subLangs = new Option<string>("--sub-langs"); private Option<bool> writeThumbnail = new Option<bool>("--write-thumbnail"); private Option<bool> noWriteThumbnail = new Option<bool>("--no-write-thumbnail"); private Option<bool> writeAllThumbnails = new Option<bool>("--write-all-thumbnails"); private Option<bool> listThumbnails = new Option<bool>("--list-thumbnails"); private Option<bool> quiet = new Option<bool>("-q", "--quiet"); private Option<bool> noQuiet = new Option<bool>("--no-quiet"); private Option<bool> noWarnings = new Option<bool>("--no-warnings"); private Option<bool> simulate = new Option<bool>("-s", "--simulate"); private Option<bool> noSimulate = new Option<bool>("--no-simulate"); private Option<bool> ignoreNoFormatsError = new Option<bool>("--ignore-no-formats-error"); private Option<bool> noIgnoreNoFormatsError = new Option<bool>("--no-ignore-no-formats-error"); private Option<bool> skipDownload = new Option<bool>("--skip-download", "--no-download"); private MultiOption<string> print = new MultiOption<string>("-O", "--print"); private MultiOption<string> printToFile = new MultiOption<string>("--print-to-file"); private Option<bool> dumpJson = new Option<bool>("-j", "--dump-json"); private Option<bool> dumpSingleJson = new Option<bool>("-J", "--dump-single-json"); private Option<bool> forceWriteArchive = new Option<bool>("--force-write-archive", "--force-download-archive"); private Option<bool> newline = new Option<bool>("--newline"); private Option<bool> noProgress = new Option<bool>("--no-progress"); private Option<bool> progress = new Option<bool>("--progress"); private Option<bool> consoleTitle = new Option<bool>("--console-title"); private Option<string> progressTemplate = new Option<string>("--progress-template"); private Option<string> progressDelta = new Option<string>("--progress-delta"); private Option<bool> verbose = new Option<bool>("-v", "--verbose"); private Option<bool> dumpPages = new Option<bool>("--dump-pages"); private Option<bool> writePages = new Option<bool>("--write-pages"); private Option<bool> printTraffic = new Option<bool>("--print-traffic"); private Option<string> format = new Option<string>("-f", "--format"); private Option<string> formatSort = new Option<string>("-S", "--format-sort"); private Option<bool> formatSortForce = new Option<bool>("--format-sort-force", "--S-force"); private Option<bool> noFormatSortForce = new Option<bool>("--no-format-sort-force"); private Option<bool> videoMultistreams = new Option<bool>("--video-multistreams"); private Option<bool> noVideoMultistreams = new Option<bool>("--no-video-multistreams"); private Option<bool> audioMultistreams = new Option<bool>("--audio-multistreams"); private Option<bool> noAudioMultistreams = new Option<bool>("--no-audio-multistreams"); private Option<bool> preferFreeFormats = new Option<bool>("--prefer-free-formats"); private Option<bool> noPreferFreeFormats = new Option<bool>("--no-prefer-free-formats"); private Option<bool> checkFormats = new Option<bool>("--check-formats"); private Option<bool> checkAllFormats = new Option<bool>("--check-all-formats"); private Option<bool> noCheckFormats = new Option<bool>("--no-check-formats"); private Option<bool> listFormats = new Option<bool>("-F", "--list-formats"); private Option<DownloadMergeFormat> mergeOutputFormat = new Option<DownloadMergeFormat>("--merge-output-format"); private Option<string> playlistItems = new Option<string>("-I", "--playlist-items"); private Option<string> minFilesize = new Option<string>("--min-filesize"); private Option<string> maxFilesize = new Option<string>("--max-filesize"); private Option<DateTime> date = new Option<DateTime>("--date"); private Option<DateTime> dateBefore = new Option<DateTime>("--datebefore"); private Option<DateTime> dateAfter = new Option<DateTime>("--dateafter"); private MultiOption<string> matchFilters = new MultiOption<string>("--match-filters"); private Option<bool> noMatchFilters = new Option<bool>("--no-match-filters"); private Option<string> breakMatchFilters = new Option<string>("--break-match-filters"); private Option<bool> noBreakMatchFilters = new Option<bool>("--no-break-match-filters"); private Option<bool> noPlaylist = new Option<bool>("--no-playlist"); private Option<bool> yesPlaylist = new Option<bool>("--yes-playlist"); private Option<byte?> ageLimit = new Option<byte?>("--age-limit"); private Option<string> downloadArchive = new Option<string>("--download-archive"); private Option<bool> noDownloadArchive = new Option<bool>("--no-download-archive"); private Option<int?> maxDownloads = new Option<int?>("--max-downloads"); private Option<bool> breakOnExisting = new Option<bool>("--break-on-existing"); private Option<bool> noBreakOnExisting = new Option<bool>("--no-break-on-existing"); private Option<bool> breakPerInput = new Option<bool>("--break-per-input"); private Option<bool> noBreakPerInput = new Option<bool>("--no-break-per-input"); private Option<int?> skipPlaylistAfterErrors = new Option<int?>("--skip-playlist-after-errors"); private Option<string> encoding = new Option<string>("--encoding"); private Option<bool> legacyServerConnect = new Option<bool>("--legacy-server-connect"); private Option<bool> noCheckCertificates = new Option<bool>("--no-check-certificates"); private Option<bool> preferInsecure = new Option<bool>("--prefer-insecure"); private MultiOption<string> addHeaders = new MultiOption<string>("--add-headers"); private Option<bool> bidiWorkaround = new Option<bool>("--bidi-workaround"); private Option<int?> sleepRequests = new Option<int?>("--sleep-requests"); private Option<int?> sleepInterval = new Option<int?>("--sleep-interval", "--min-sleep-interval"); private Option<int?> maxSleepInterval = new Option<int?>("--max-sleep-interval"); private Option<int?> sleepSubtitles = new Option<int?>("--sleep-subtitles"); public string Username { get { return username.Value; } set { username.Value = value; } } public string Password { get { return password.Value; } set { password.Value = value; } } public string TwoFactor { get { return twoFactor.Value; } set { twoFactor.Value = value; } } public bool Netrc { get { return netrc.Value; } set { netrc.Value = value; } } public string NetrcLocation { get { return netrcLocation.Value; } set { netrcLocation.Value = value; } } public string NetrcCmd { get { return netrcCmd.Value; } set { netrcCmd.Value = value; } } public string VideoPassword { get { return videoPassword.Value; } set { videoPassword.Value = value; } } public string ApMso { get { return apMso.Value; } set { apMso.Value = value; } } public string ApUsername { get { return apUsername.Value; } set { apUsername.Value = value; } } public string ApPassword { get { return apPassword.Value; } set { apPassword.Value = value; } } public bool ApListMso { get { return apListMso.Value; } set { apListMso.Value = value; } } public string ClientCertificate { get { return clientCertificate.Value; } set { clientCertificate.Value = value; } } public string ClientCertificateKey { get { return clientCertificateKey.Value; } set { clientCertificateKey.Value = value; } } public string ClientCertificatePassword { get { return clientCertificatePassword.Value; } set { clientCertificatePassword.Value = value; } } public IOption[] CustomOptions { get; set; } = new IOption[0]; [Obsolete("Deprecated in favor of: --print description.")] public bool GetDescription { get { return getDescription.Value; } set { getDescription.Value = value; } } [Obsolete("Deprecated in favor of: --print duration_string.")] public bool GetDuration { get { return getDuration.Value; } set { getDuration.Value = value; } } [Obsolete("Deprecated in favor of: --print filename.")] public bool GetFilename { get { return getFilename.Value; } set { getFilename.Value = value; } } [Obsolete("Deprecated in favor of: --print format.")] public bool GetFormat { get { return getFormat.Value; } set { getFormat.Value = value; } } [Obsolete("Deprecated in favor of: --print id.")] public bool GetId { get { return getId.Value; } set { getId.Value = value; } } [Obsolete("Deprecated in favor of: --print thumbnail.")] public bool GetThumbnail { get { return getThumbnail.Value; } set { getThumbnail.Value = value; } } [Obsolete("Deprecated in favor of: --print title.")] public bool GetTitle { get { return getTitle.Value; } set { getTitle.Value = value; } } [Obsolete("Deprecated in favor of: --print urls.")] public bool GetUrl { get { return getUrl.Value; } set { getUrl.Value = value; } } [Obsolete("Deprecated in favor of: --match-filter \"title ~= (?i)REGEX\".")] public string MatchTitle { get { return matchTitle.Value; } set { matchTitle.Value = value; } } [Obsolete("Deprecated in favor of: --match-filter \"title !~= (?i)REGEX\".")] public string RejectTitle { get { return rejectTitle.Value; } set { rejectTitle.Value = value; } } [Obsolete("Deprecated in favor of: --match-filter \"view_count >=? COUNT\".")] public long? MinViews { get { return minViews.Value; } set { minViews.Value = value; } } [Obsolete("Deprecated in favor of: --match-filter \"view_count <=? COUNT\".")] public long? MaxViews { get { return maxViews.Value; } set { maxViews.Value = value; } } [Obsolete("Deprecated in favor of: Use --break-match-filter.")] public bool BreakOnReject { get { return breakOnReject.Value; } set { breakOnReject.Value = value; } } [Obsolete("Deprecated in favor of: --add-header \"User-Agent:UA\".")] public string UserAgent { get { return userAgent.Value; } set { userAgent.Value = value; } } [Obsolete("Deprecated in favor of: --add-header \"Referer:URL\".")] public string Referer { get { return referer.Value; } set { referer.Value = value; } } [Obsolete("Deprecated in favor of: -I NUMBER:.")] public int? PlaylistStart { get { return playlistStart.Value; } set { playlistStart.Value = value; } } [Obsolete("Deprecated in favor of: -I :NUMBER.")] public int? PlaylistEnd { get { return playlistEnd.Value; } set { playlistEnd.Value = value; } } [Obsolete("Deprecated in favor of: -I ::-1.")] public bool PlaylistReverse { get { return playlistReverse.Value; } set { playlistReverse.Value = value; } } [Obsolete("Deprecated in favor of: --color no_color.")] public bool NoColors { get { return noColors.Value; } set { noColors.Value = value; } } [Obsolete("Deprecated in favor of: --ies generic,default.")] public bool ForceGenericExtractor { get { return forceGenericExtractor.Value; } set { forceGenericExtractor.Value = value; } } [Obsolete("Deprecated in favor of: --exec \"before_dl:CMD\".")] public string ExecBeforeDownload { get { return execBeforeDownload.Value; } set { execBeforeDownload.Value = value; } } [Obsolete("Deprecated in favor of: --no-exec.")] public bool NoExecBeforeDownload { get { return noExecBeforeDownload.Value; } set { noExecBeforeDownload.Value = value; } } [Obsolete("Deprecated in favor of: -f all.")] public bool AllFormats { get { return allFormats.Value; } set { allFormats.Value = value; } } [Obsolete("Deprecated in favor of: --sub-langs all --write-subs.")] public bool AllSubs { get { return allSubs.Value; } set { allSubs.Value = value; } } [Obsolete("Deprecated in favor of: -j --no-simulate.")] public bool PrintJson { get { return printJson.Value; } set { printJson.Value = value; } } [Obsolete("Deprecated in favor of: Use string formatting, e.g. %(autonumber)03d.")] public string AutonumberSize { get { return autonumberSize.Value; } set { autonumberSize.Value = value; } } [Obsolete("Deprecated in favor of: Use internal field formatting like %(autonumber+NUMBER)s.")] public int? AutonumberStart { get { return autonumberStart.Value; } set { autonumberStart.Value = value; } } [Obsolete("Deprecated in favor of: -o \"%(id)s.%(ext)s\".")] public bool Id { get { return id.Value; } set { id.Value = value; } } [Obsolete("Deprecated in favor of: --parse-metadata \"%(title)s:FORMAT\".")] public string MetadataFromTitle { get { return metadataFromTitle.Value; } set { metadataFromTitle.Value = value; } } [Obsolete("Deprecated in favor of: --downloader \"m3u8:native\".")] public bool HlsPreferNative { get { return hlsPreferNative.Value; } set { hlsPreferNative.Value = value; } } [Obsolete("Deprecated in favor of: --downloader \"m3u8:ffmpeg\".")] public bool HlsPreferFfmpeg { get { return hlsPreferFfmpeg.Value; } set { hlsPreferFfmpeg.Value = value; } } [Obsolete("Deprecated in favor of: --compat-options list-formats (Alias: --no-list-formats-as-table).")] public bool ListFormatsOld { get { return listFormatsOld.Value; } set { listFormatsOld.Value = value; } } [Obsolete("Deprecated in favor of: --compat-options -list-formats [Default] (Alias: --no-list-formats-old).")] public bool ListFormatsAsTable { get { return listFormatsAsTable.Value; } set { listFormatsAsTable.Value = value; } } [Obsolete("Deprecated in favor of: --extractor-args \"youtube:skip=dash\" (Alias: --no-youtube-include-dash-manifest).")] public bool YoutubeSkipDashManifest { get { return youtubeSkipDashManifest.Value; } set { youtubeSkipDashManifest.Value = value; } } [Obsolete("Deprecated in favor of: --extractor-args \"youtube:skip=hls\" (Alias: --no-youtube-include-hls-manifest).")] public bool YoutubeSkipHlsManifest { get { return youtubeSkipHlsManifest.Value; } set { youtubeSkipHlsManifest.Value = value; } } [Obsolete("Deprecated in favor of: --xff \"default\".")] public bool GeoBypass { get { return geoBypass.Value; } set { geoBypass.Value = value; } } [Obsolete("Deprecated in favor of: --xff \"never\".")] public bool NoGeoBypass { get { return noGeoBypass.Value; } set { noGeoBypass.Value = value; } } [Obsolete("Deprecated in favor of: --xff CODE.")] public string GeoBypassCountry { get { return geoBypassCountry.Value; } set { geoBypassCountry.Value = value; } } [Obsolete("Deprecated in favor of: --xff IP_BLOCK.")] public string GeoBypassIpBlock { get { return geoBypassIpBlock.Value; } set { geoBypassIpBlock.Value = value; } } public int? ConcurrentFragments { get { return concurrentFragments.Value; } set { concurrentFragments.Value = value; } } public long? LimitRate { get { return limitRate.Value; } set { limitRate.Value = value; } } public long? ThrottledRate { get { return throttledRate.Value; } set { throttledRate.Value = value; } } public int? Retries { get { return retries.Value; } set { retries.Value = value; } } public int? FileAccessRetries { get { return fileAccessRetries.Value; } set { fileAccessRetries.Value = value; } } public int? FragmentRetries { get { return fragmentRetries.Value; } set { fragmentRetries.Value = value; } } public MultiValue<string> RetrySleep { get { return retrySleep.Value; } set { retrySleep.Value = value; } } public bool SkipUnavailableFragments { get { return skipUnavailableFragments.Value; } set { skipUnavailableFragments.Value = value; } } public bool AbortOnUnavailableFragments { get { return abortOnUnavailableFragments.Value; } set { abortOnUnavailableFragments.Value = value; } } public bool KeepFragments { get { return keepFragments.Value; } set { keepFragments.Value = value; } } public bool NoKeepFragments { get { return noKeepFragments.Value; } set { noKeepFragments.Value = value; } } public long? BufferSize { get { return bufferSize.Value; } set { bufferSize.Value = value; } } public bool ResizeBuffer { get { return resizeBuffer.Value; } set { resizeBuffer.Value = value; } } public bool NoResizeBuffer { get { return noResizeBuffer.Value; } set { noResizeBuffer.Value = value; } } public long? HttpChunkSize { get { return httpChunkSize.Value; } set { httpChunkSize.Value = value; } } public bool PlaylistRandom { get { return playlistRandom.Value; } set { playlistRandom.Value = value; } } public bool LazyPlaylist { get { return lazyPlaylist.Value; } set { lazyPlaylist.Value = value; } } public bool NoLazyPlaylist { get { return noLazyPlaylist.Value; } set { noLazyPlaylist.Value = value; } } public bool HlsUseMpegts { get { return hlsUseMpegts.Value; } set { hlsUseMpegts.Value = value; } } public bool NoHlsUseMpegts { get { return noHlsUseMpegts.Value; } set { noHlsUseMpegts.Value = value; } } public MultiValue<string> DownloadSections { get { return downloadSections.Value; } set { downloadSections.Value = value; } } public MultiValue<string> Downloader { get { return downloader.Value; } set { downloader.Value = value; } } public MultiValue<string> DownloaderArgs { get { return downloaderArgs.Value; } set { downloaderArgs.Value = value; } } public int? ExtractorRetries { get { return extractorRetries.Value; } set { extractorRetries.Value = value; } } public bool AllowDynamicMpd { get { return allowDynamicMpd.Value; } set { allowDynamicMpd.Value = value; } } public bool IgnoreDynamicMpd { get { return ignoreDynamicMpd.Value; } set { ignoreDynamicMpd.Value = value; } } public bool HlsSplitDiscontinuity { get { return hlsSplitDiscontinuity.Value; } set { hlsSplitDiscontinuity.Value = value; } } public bool NoHlsSplitDiscontinuity { get { return noHlsSplitDiscontinuity.Value; } set { noHlsSplitDiscontinuity.Value = value; } } public MultiValue<string> ExtractorArgs { get { return extractorArgs.Value; } set { extractorArgs.Value = value; } } public string BatchFile { get { return batchFile.Value; } set { batchFile.Value = value; } } public bool NoBatchFile { get { return noBatchFile.Value; } set { noBatchFile.Value = value; } } public MultiValue<string> Paths { get { return paths.Value; } set { paths.Value = value; } } public string Output { get { return output.Value; } set { output.Value = value; } } public string OutputNaPlaceholder { get { return outputNaPlaceholder.Value; } set { outputNaPlaceholder.Value = value; } } public bool RestrictFilenames { get { return restrictFilenames.Value; } set { restrictFilenames.Value = value; } } public bool NoRestrictFilenames { get { return noRestrictFilenames.Value; } set { noRestrictFilenames.Value = value; } } public bool WindowsFilenames { get { return windowsFilenames.Value; } set { windowsFilenames.Value = value; } } public bool NoWindowsFilenames { get { return noWindowsFilenames.Value; } set { noWindowsFilenames.Value = value; } } public int? TrimFilenames { get { return trimFilenames.Value; } set { trimFilenames.Value = value; } } public bool NoOverwrites { get { return noOverwrites.Value; } set { noOverwrites.Value = value; } } public bool ForceOverwrites { get { return forceOverwrites.Value; } set { forceOverwrites.Value = value; } } public bool NoForceOverwrites { get { return noForceOverwrites.Value; } set { noForceOverwrites.Value = value; } } public bool Continue { get { return doContinue.Value; } set { doContinue.Value = value; } } public bool NoContinue { get { return noContinue.Value; } set { noContinue.Value = value; } } public bool Part { get { return part.Value; } set { part.Value = value; } } public bool NoPart { get { return noPart.Value; } set { noPart.Value = value; } } public bool Mtime { get { return mtime.Value; } set { mtime.Value = value; } } public bool NoMtime { get { return noMtime.Value; } set { noMtime.Value = value; } } public bool WriteDescription { get { return writeDescription.Value; } set { writeDescription.Value = value; } } public bool NoWriteDescription { get { return noWriteDescription.Value; } set { noWriteDescription.Value = value; } } public bool WriteInfoJson { get { return writeInfoJson.Value; } set { writeInfoJson.Value = value; } } public bool NoWriteInfoJson { get { return noWriteInfoJson.Value; } set { noWriteInfoJson.Value = value; } } public bool WritePlaylistMetafiles { get { return writePlaylistMetafiles.Value; } set { writePlaylistMetafiles.Value = value; } } public bool NoWritePlaylistMetafiles { get { return noWritePlaylistMetafiles.Value; } set { noWritePlaylistMetafiles.Value = value; } } public bool CleanInfoJson { get { return cleanInfoJson.Value; } set { cleanInfoJson.Value = value; } } public bool NoCleanInfoJson { get { return noCleanInfoJson.Value; } set { noCleanInfoJson.Value = value; } } public bool WriteComments { get { return writeComments.Value; } set { writeComments.Value = value; } } public bool NoWriteComments { get { return noWriteComments.Value; } set { noWriteComments.Value = value; } } public string LoadInfoJson { get { return loadInfoJson.Value; } set { loadInfoJson.Value = value; } } public string Cookies { get { return cookies.Value; } set { cookies.Value = value; } } public bool NoCookies { get { return noCookies.Value; } set { noCookies.Value = value; } } public string CookiesFromBrowser { get { return cookiesFromBrowser.Value; } set { cookiesFromBrowser.Value = value; } } public bool NoCookiesFromBrowser { get { return noCookiesFromBrowser.Value; } set { noCookiesFromBrowser.Value = value; } } public string CacheDir { get { return cacheDir.Value; } set { cacheDir.Value = value; } } public bool NoCacheDir { get { return noCacheDir.Value; } set { noCacheDir.Value = value; } } public bool RemoveCacheDir { get { return removeCacheDir.Value; } set { removeCacheDir.Value = value; } } public bool Help { get { return help.Value; } set { help.Value = value; } } public bool Version { get { return version.Value; } set { version.Value = value; } } public bool Update { get { return update.Value; } set { update.Value = value; } } public bool NoUpdate { get { return noUpdate.Value; } set { noUpdate.Value = value; } } public string UpdateTo { get { return updateTo.Value; } set { updateTo.Value = value; } } public bool IgnoreErrors { get { return ignoreErrors.Value; } set { ignoreErrors.Value = value; } } public bool NoAbortOnError { get { return noAbortOnError.Value; } set { noAbortOnError.Value = value; } } public bool AbortOnError { get { return abortOnError.Value; } set { abortOnError.Value = value; } } public bool ListExtractors { get { return listExtractors.Value; } set { listExtractors.Value = value; } } public bool ExtractorDescriptions { get { return extractorDescriptions.Value; } set { extractorDescriptions.Value = value; } } public string UseExtractors { get { return useExtractors.Value; } set { useExtractors.Value = value; } } public string DefaultSearch { get { return defaultSearch.Value; } set { defaultSearch.Value = value; } } public bool IgnoreConfig { get { return ignoreConfig.Value; } set { ignoreConfig.Value = value; } } public bool NoConfigLocations { get { return noConfigLocations.Value; } set { noConfigLocations.Value = value; } } public MultiValue<string> ConfigLocations { get { return configLocations.Value; } set { configLocations.Value = value; } } public MultiValue<string> PluginDirs { get { return pluginDirs.Value; } set { pluginDirs.Value = value; } } public bool NoPluginDirs { get { return noPluginDirs.Value; } set { noPluginDirs.Value = value; } } public MultiValue<string> JsRuntimes { get { return jsRuntimes.Value; } set { jsRuntimes.Value = value; } } public bool NoJsRuntimes { get { return noJsRuntimes.Value; } set { noJsRuntimes.Value = value; } } public MultiValue<string> RemoteComponents { get { return remoteComponents.Value; } set { remoteComponents.Value = value; } } public bool NoRemoteComponents { get { return noRemoteComponents.Value; } set { noRemoteComponents.Value = value; } } public bool FlatPlaylist { get { return flatPlaylist.Value; } set { flatPlaylist.Value = value; } } public bool NoFlatPlaylist { get { return noFlatPlaylist.Value; } set { noFlatPlaylist.Value = value; } } public bool LiveFromStart { get { return liveFromStart.Value; } set { liveFromStart.Value = value; } } public bool NoLiveFromStart { get { return noLiveFromStart.Value; } set { noLiveFromStart.Value = value; } } public string WaitForVideo { get { return waitForVideo.Value; } set { waitForVideo.Value = value; } } public bool NoWaitForVideo { get { return noWaitForVideo.Value; } set { noWaitForVideo.Value = value; } } public bool MarkWatched { get { return markWatched.Value; } set { markWatched.Value = value; } } public bool NoMarkWatched { get { return noMarkWatched.Value; } set { noMarkWatched.Value = value; } } public MultiValue<string> Color { get { return color.Value; } set { color.Value = value; } } public string CompatOptions { get { return compatOptions.Value; } set { compatOptions.Value = value; } } public MultiValue<StringVals> Alias { get { return alias.Value; } set { alias.Value = value; } } public MultiValue<string> PresetAlias { get { return presetAlias.Value; } set { presetAlias.Value = value; } } public string GeoVerificationProxy { get { return geoVerificationProxy.Value; } set { geoVerificationProxy.Value = value; } } public string Xff { get { return xff.Value; } set { xff.Value = value; } } public bool WriteLink { get { return writeLink.Value; } set { writeLink.Value = value; } } public bool WriteUrlLink { get { return writeUrlLink.Value; } set { writeUrlLink.Value = value; } } public bool WriteWeblocLink { get { return writeWeblocLink.Value; } set { writeWeblocLink.Value = value; } } public bool WriteDesktopLink { get { return writeDesktopLink.Value; } set { writeDesktopLink.Value = value; } } public string Proxy { get { return proxy.Value; } set { proxy.Value = value; } } public int? SocketTimeout { get { return socketTimeout.Value; } set { socketTimeout.Value = value; } } public string SourceAddress { get { return sourceAddress.Value; } set { sourceAddress.Value = value; } } public string Impersonate { get { return impersonate.Value; } set { impersonate.Value = value; } } public bool ListImpersonateTargets { get { return listImpersonateTargets.Value; } set { listImpersonateTargets.Value = value; } } public bool ForceIPv4 { get { return forceIPv4.Value; } set { forceIPv4.Value = value; } } public bool ForceIPv6 { get { return forceIPv6.Value; } set { forceIPv6.Value = value; } } public bool EnableFileUrls { get { return enableFileUrls.Value; } set { enableFileUrls.Value = value; } } public bool ExtractAudio { get { return extractAudio.Value; } set { extractAudio.Value = value; } } public AudioConversionFormat AudioFormat { get { return audioFormat.Value; } set { audioFormat.Value = value; } } public byte? AudioQuality { get { return audioQuality.Value; } set { audioQuality.Value = value; } } public string RemuxVideo { get { return remuxVideo.Value; } set { remuxVideo.Value = value; } } public VideoRecodeFormat RecodeVideo { get { return recodeVideo.Value; } set { recodeVideo.Value = value; } } public MultiValue<string> PostprocessorArgs { get { return postprocessorArgs.Value; } set { postprocessorArgs.Value = value; } } public bool KeepVideo { get { return keepVideo.Value; } set { keepVideo.Value = value; } } public bool NoKeepVideo { get { return noKeepVideo.Value; } set { noKeepVideo.Value = value; } } public bool PostOverwrites { get { return postOverwrites.Value; } set { postOverwrites.Value = value; } } public bool NoPostOverwrites { get { return noPostOverwrites.Value; } set { noPostOverwrites.Value = value; } } public bool EmbedSubs { get { return embedSubs.Value; } set { embedSubs.Value = value; } } public bool NoEmbedSubs { get { return noEmbedSubs.Value; } set { noEmbedSubs.Value = value; } } public bool EmbedThumbnail { get { return embedThumbnail.Value; } set { embedThumbnail.Value = value; } } public bool NoEmbedThumbnail { get { return noEmbedThumbnail.Value; } set { noEmbedThumbnail.Value = value; } } public bool EmbedMetadata { get { return embedMetadata.Value; } set { embedMetadata.Value = value; } } public bool NoEmbedMetadata { get { return noEmbedMetadata.Value; } set { noEmbedMetadata.Value = value; } } public bool EmbedChapters { get { return embedChapters.Value; } set { embedChapters.Value = value; } } public bool NoEmbedChapters { get { return noEmbedChapters.Value; } set { noEmbedChapters.Value = value; } } public bool EmbedInfoJson { get { return embedInfoJson.Value; } set { embedInfoJson.Value = value; } } public bool NoEmbedInfoJson { get { return noEmbedInfoJson.Value; } set { noEmbedInfoJson.Value = value; } } public string ParseMetadata { get { return parseMetadata.Value; } set { parseMetadata.Value = value; } } public MultiValue<StringVals> ReplaceInMetadata { get { return replaceInMetadata.Value; } set { replaceInMetadata.Value = value; } } public bool Xattrs { get { return xattrs.Value; } set { xattrs.Value = value; } } public string ConcatPlaylist { get { return concatPlaylist.Value; } set { concatPlaylist.Value = value; } } public string Fixup { get { return fixup.Value; } set { fixup.Value = value; } } public string FfmpegLocation { get { return ffmpegLocation.Value; } set { ffmpegLocation.Value = value; } } public MultiValue<string> Exec { get { return exec.Value; } set { exec.Value = value; } } public bool NoExec { get { return noExec.Value; } set { noExec.Value = value; } } public string ConvertSubs { get { return convertSubs.Value; } set { convertSubs.Value = value; } } public string ConvertThumbnails { get { return convertThumbnails.Value; } set { convertThumbnails.Value = value; } } public bool SplitChapters { get { return splitChapters.Value; } set { splitChapters.Value = value; } } public bool NoSplitChapters { get { return noSplitChapters.Value; } set { noSplitChapters.Value = value; } } public MultiValue<string> RemoveChapters { get { return removeChapters.Value; } set { removeChapters.Value = value; } } public bool NoRemoveChapters { get { return noRemoveChapters.Value; } set { noRemoveChapters.Value = value; } } public bool ForceKeyframesAtCuts { get { return forceKeyframesAtCuts.Value; } set { forceKeyframesAtCuts.Value = value; } } public bool NoForceKeyframesAtCuts { get { return noForceKeyframesAtCuts.Value; } set { noForceKeyframesAtCuts.Value = value; } } public MultiValue<string> UsePostprocessor { get { return usePostprocessor.Value; } set { usePostprocessor.Value = value; } } public string SponsorblockMark { get { return sponsorblockMark.Value; } set { sponsorblockMark.Value = value; } } public string SponsorblockRemove { get { return sponsorblockRemove.Value; } set { sponsorblockRemove.Value = value; } } public string SponsorblockChapterTitle { get { return sponsorblockChapterTitle.Value; } set { sponsorblockChapterTitle.Value = value; } } public bool NoSponsorblock { get { return noSponsorblock.Value; } set { noSponsorblock.Value = value; } } public string SponsorblockApi { get { return sponsorblockApi.Value; } set { sponsorblockApi.Value = value; } } public bool WriteSubs { get { return writeSubs.Value; } set { writeSubs.Value = value; } } public bool NoWriteSubs { get { return noWriteSubs.Value; } set { noWriteSubs.Value = value; } } public bool WriteAutoSubs { get { return writeAutoSubs.Value; } set { writeAutoSubs.Value = value; } } public bool NoWriteAutoSubs { get { return noWriteAutoSubs.Value; } set { noWriteAutoSubs.Value = value; } } public bool ListSubs { get { return listSubs.Value; } set { listSubs.Value = value; } } public string SubFormat { get { return subFormat.Value; } set { subFormat.Value = value; } } public string SubLangs { get { return subLangs.Value; } set { subLangs.Value = value; } } public bool WriteThumbnail { get { return writeThumbnail.Value; } set { writeThumbnail.Value = value; } } public bool NoWriteThumbnail { get { return noWriteThumbnail.Value; } set { noWriteThumbnail.Value = value; } } public bool WriteAllThumbnails { get { return writeAllThumbnails.Value; } set { writeAllThumbnails.Value = value; } } public bool ListThumbnails { get { return listThumbnails.Value; } set { listThumbnails.Value = value; } } public bool Quiet { get { return quiet.Value; } set { quiet.Value = value; } } public bool NoQuiet { get { return noQuiet.Value; } set { noQuiet.Value = value; } } public bool NoWarnings { get { return noWarnings.Value; } set { noWarnings.Value = value; } } public bool Simulate { get { return simulate.Value; } set { simulate.Value = value; } } public bool NoSimulate { get { return noSimulate.Value; } set { noSimulate.Value = value; } } public bool IgnoreNoFormatsError { get { return ignoreNoFormatsError.Value; } set { ignoreNoFormatsError.Value = value; } } public bool NoIgnoreNoFormatsError { get { return noIgnoreNoFormatsError.Value; } set { noIgnoreNoFormatsError.Value = value; } } public bool SkipDownload { get { return skipDownload.Value; } set { skipDownload.Value = value; } } public MultiValue<string> Print { get { return print.Value; } set { print.Value = value; } } public MultiValue<string> PrintToFile { get { return printToFile.Value; } set { printToFile.Value = value; } } public bool DumpJson { get { return dumpJson.Value; } set { dumpJson.Value = value; } } public bool DumpSingleJson { get { return dumpSingleJson.Value; } set { dumpSingleJson.Value = value; } } public bool ForceWriteArchive { get { return forceWriteArchive.Value; } set { forceWriteArchive.Value = value; } } public bool Newline { get { return newline.Value; } set { newline.Value = value; } } public bool NoProgress { get { return noProgress.Value; } set { noProgress.Value = value; } } public bool Progress { get { return progress.Value; } set { progress.Value = value; } } public bool ConsoleTitle { get { return consoleTitle.Value; } set { consoleTitle.Value = value; } } public string ProgressTemplate { get { return progressTemplate.Value; } set { progressTemplate.Value = value; } } public string ProgressDelta { get { return progressDelta.Value; } set { progressDelta.Value = value; } } public bool Verbose { get { return verbose.Value; } set { verbose.Value = value; } } public bool DumpPages { get { return dumpPages.Value; } set { dumpPages.Value = value; } } public bool WritePages { get { return writePages.Value; } set { writePages.Value = value; } } public bool PrintTraffic { get { return printTraffic.Value; } set { printTraffic.Value = value; } } public string Format { get { return format.Value; } set { format.Value = value; } } public string FormatSort { get { return formatSort.Value; } set { formatSort.Value = value; } } public bool FormatSortForce { get { return formatSortForce.Value; } set { formatSortForce.Value = value; } } public bool NoFormatSortForce { get { return noFormatSortForce.Value; } set { noFormatSortForce.Value = value; } } public bool VideoMultistreams { get { return videoMultistreams.Value; } set { videoMultistreams.Value = value; } } public bool NoVideoMultistreams { get { return noVideoMultistreams.Value; } set { noVideoMultistreams.Value = value; } } public bool AudioMultistreams { get { return audioMultistreams.Value; } set { audioMultistreams.Value = value; } } public bool NoAudioMultistreams { get { return noAudioMultistreams.Value; } set { noAudioMultistreams.Value = value; } } public bool PreferFreeFormats { get { return preferFreeFormats.Value; } set { preferFreeFormats.Value = value; } } public bool NoPreferFreeFormats { get { return noPreferFreeFormats.Value; } set { noPreferFreeFormats.Value = value; } } public bool CheckFormats { get { return checkFormats.Value; } set { checkFormats.Value = value; } } public bool CheckAllFormats { get { return checkAllFormats.Value; } set { checkAllFormats.Value = value; } } public bool NoCheckFormats { get { return noCheckFormats.Value; } set { noCheckFormats.Value = value; } } public bool ListFormats { get { return listFormats.Value; } set { listFormats.Value = value; } } public DownloadMergeFormat MergeOutputFormat { get { return mergeOutputFormat.Value; } set { mergeOutputFormat.Value = value; } } public string PlaylistItems { get { return playlistItems.Value; } set { playlistItems.Value = value; } } public string MinFilesize { get { return minFilesize.Value; } set { minFilesize.Value = value; } } public string MaxFilesize { get { return maxFilesize.Value; } set { maxFilesize.Value = value; } } public DateTime Date { get { return date.Value; } set { date.Value = value; } } public DateTime DateBefore { get { return dateBefore.Value; } set { dateBefore.Value = value; } } public DateTime DateAfter { get { return dateAfter.Value; } set { dateAfter.Value = value; } } public MultiValue<string> MatchFilters { get { return matchFilters.Value; } set { matchFilters.Value = value; } } public bool NoMatchFilters { get { return noMatchFilters.Value; } set { noMatchFilters.Value = value; } } public string BreakMatchFilters { get { return breakMatchFilters.Value; } set { breakMatchFilters.Value = value; } } public bool NoBreakMatchFilters { get { return noBreakMatchFilters.Value; } set { noBreakMatchFilters.Value = value; } } public bool NoPlaylist { get { return noPlaylist.Value; } set { noPlaylist.Value = value; } } public bool YesPlaylist { get { return yesPlaylist.Value; } set {