Decompiled source of YPlayBoombox v2.2.1
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.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DamienG.Security.Cryptography; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Networking; using UnityEngine.SceneManagement; using YPlay.NetcodePatcher; using YPlayUtil; using YPlayUtil.Helpers; 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] internal class <Module> { static <Module>() { } } 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 DamienG.Security.Cryptography { public sealed class Crc32 : HashAlgorithm { public const uint DefaultPolynomial = 3988292384u; public const uint DefaultSeed = uint.MaxValue; private static uint[] defaultTable; private readonly uint seed; private readonly uint[] table; private uint hash; public override int HashSize => 32; public Crc32() : this(3988292384u, uint.MaxValue) { } public Crc32(uint polynomial, uint seed) { if (!BitConverter.IsLittleEndian) { throw new PlatformNotSupportedException("Not supported on Big Endian processors"); } table = InitializeTable(polynomial); this.seed = (hash = seed); } public override void Initialize() { hash = seed; } protected override void HashCore(byte[] array, int ibStart, int cbSize) { hash = CalculateHash(table, hash, array, ibStart, cbSize); } protected override byte[] HashFinal() { return HashValue = UInt32ToBigEndianBytes(~hash); } public static uint Compute(byte[] buffer) { return Compute(uint.MaxValue, buffer); } public static uint Compute(uint seed, byte[] buffer) { return Compute(3988292384u, seed, buffer); } public static uint Compute(uint polynomial, uint seed, byte[] buffer) { return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); } private static uint[] InitializeTable(uint polynomial) { if (polynomial == 3988292384u && defaultTable != null) { return defaultTable; } uint[] array = new uint[256]; for (int i = 0; i < 256; i++) { uint num = (uint)i; for (int j = 0; j < 8; j++) { num = (((num & 1) != 1) ? (num >> 1) : ((num >> 1) ^ polynomial)); } array[i] = num; } if (polynomial == 3988292384u) { defaultTable = array; } return array; } private static uint CalculateHash(uint[] table, uint seed, IList<byte> buffer, int start, int size) { uint num = seed; for (int i = start; i < start + size; i++) { num = (num >> 8) ^ table[buffer[i] ^ (num & 0xFF)]; } return num; } private static byte[] UInt32ToBigEndianBytes(uint uint32) { byte[] bytes = BitConverter.GetBytes(uint32); if (BitConverter.IsLittleEndian) { Array.Reverse((Array)bytes); } return bytes; } } } namespace YPlay { internal class BoomboxAudioLoader : MonoBehaviour { internal static readonly Dictionary<string, AudioClip> filenameIdAudioClips = new Dictionary<string, AudioClip>(); internal static readonly List<string> filenameIdsDownloaded = new List<string>(); private static BoomboxAudioLoader 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(BoomboxAudioLoader).Name).AddComponent<BoomboxAudioLoader>(); Object.DontDestroyOnLoad((Object)(object)Instance); } ((MonoBehaviour)Instance).StartCoroutine(routine); } internal IEnumerator GetAudioClip(BoomboxItemController boomboxItemController, int requestId, string path, bool resync) { string filenameId = Path.GetFileNameWithoutExtension(path); bool flag = false; bool success = false; if (filenameIdAudioClips.ContainsKey(filenameId)) { AudioClip audioClip = filenameIdAudioClips[filenameId]; if (Object.op_Implicit((Object)(object)audioClip) && (int)audioClip.loadState == 2) { yield return null; SetAudio(filenameId, audioClip); flag = true; success = true; } else { filenameIdAudioClips.Remove(filenameId); } } bool flag2 = BoomboxAudioDownloader.IsFilenameIdDownloaded(filenameId); if (!flag && flag2) { if (filenameIdsDownloaded.Contains(filenameId)) { filenameIdsDownloaded.Remove(filenameId); } filenameIdsDownloaded.Insert(0, filenameId); AudioType audioType = BoomboxAudioDownloader.audioType; UnityWebRequest unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(path, audioType); try { ((DownloadHandlerAudioClip)unityWebRequest.downloadHandler).streamAudio = (int)audioType == 13; yield return unityWebRequest.SendWebRequest(); if ((int)unityWebRequest.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(unityWebRequest); if ((int)content.loadState == 2) { boomboxItemController.audioType = audioType; SetAudio(filenameId, content); success = true; } } } finally { ((IDisposable)unityWebRequest)?.Dispose(); } } if (!success) { string text = "Error " + (resync ? "resyncing" : "loading") + " request " + BoomboxAudioDownloader.GetFilenameIdString(filenameId); YPlay.LogWarning(text); YPlayCorePatch.AddChatMessageYP(text); } boomboxItemController.SendBoomboxLoadedServerDelegate(requestId, success, 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 void SetAudio(string filenameId, AudioClip audioClip) { filenameIdAudioClips[filenameId] = audioClip; YPlayCorePatch.AddChatMessageYP("Loaded " + BoomboxAudioDownloader.GetFilenameIdString(filenameId)); } } internal class BoomboxAudioDownloader { [CompilerGenerated] private BoomboxItemController <boomboxItemController>P; 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 BoomboxAudioLoader boomboxAudioLoader; private BoomboxAudioAction boomboxAudioAction; internal static HashSet<string> filenameIdsResyncing = new HashSet<string>(); internal static string audioTypeExtension = "mp3"; internal static AudioType audioType = (AudioType)13; private static readonly OptionSet optionSet = new OptionSet { NoPlaylist = true, ForceIPv4 = true }; public BoomboxAudioDownloader(BoomboxItemController boomboxItemController) { <boomboxItemController>P = boomboxItemController; lastDownloadRequestId = -1; boomboxAudioLoader = new BoomboxAudioLoader(); base..ctor(); } internal async void DownloadTask(int requestId, string filenameId, string title, int duration, string url, float time, bool resync = false) { if (string.IsNullOrEmpty(filenameId?.Trim()) || string.IsNullOrEmpty(title?.Trim()) || string.IsNullOrEmpty(url?.Trim())) { YPlayCorePatch.AddChatMessageYP("Invalid " + (resync ? "resync" : "download") + " request"); return; } if (resync) { filenameIdsResyncing.Add(filenameId); } lastDownloadRequestId = requestId; lastDownloadRequestFilenameId = filenameId; time = Mathf.Max(time, 0f); POST_TASK postTask = POST_TASK.NONE; audioIdTitles[filenameId] = title; audioIdDurations[filenameId] = duration; await Task.Run(delegate { string outputFileLocationForId = GetOutputFileLocationForId(filenameId); CancelCurrentProcess(); if (IsFilenameLoaded(filenameId)) { postTask = LoadFile(filenameId, outputFileLocationForId, requestId, resync); } else if (!YPlay.IsYPlayUtilValid()) { postTask = POST_TASK.ERROR_MISSING_DEPENDENCY; } else if (YPlay.IsDownloadingTools()) { postTask = POST_TASK.ERROR_DOWNLOADING_TOOLS; } else if (!YPlay.IsToolsExistAndNonEmpty()) { postTask = POST_TASK.ERROR_INVALID_TOOLS; } else { boomboxAudioAction = new BoomboxAudioAction(this, requestId, filenameId, outputFileLocationForId, url); postTask = boomboxAudioAction.Start(resync); } }); string text = null; RLE_REASON rLE_REASON = RLE_REASON.NONE; switch (postTask) { case POST_TASK.ERROR_MISSING_DEPENDENCY: rLE_REASON = RLE_REASON.MISSING_DEPENDENCY; text = "Missing dependency, please try reinstalling YPlayBoombox"; break; case POST_TASK.ERROR_DOWNLOADING_TOOLS: rLE_REASON = RLE_REASON.DOWNLOADING_TOOLS; text = "Downloading tools..."; break; case POST_TASK.ERROR_INVALID_TOOLS: rLE_REASON = RLE_REASON.INVALID_TOOLS; text = "Invalid tools, please try /yp reset-tools"; break; case POST_TASK.ERROR_DOWNLOADING_AUDIO: rLE_REASON = RLE_REASON.FAILED_DOWNLOAD; text = "Error downloading request " + GetFilenameIdString(filenameId); break; case POST_TASK.ERROR_LOADING_AUDIO: rLE_REASON = RLE_REASON.FAILED_LOAD; text = "Error loading request " + GetFilenameIdString(filenameId); break; } if (rLE_REASON != 0) { <boomboxItemController>P.SendBoomboxLoadedServerDelegate(requestId, loaded: false, resync, rLE_REASON); YPlay.LogError(text); YPlayCorePatch.AddChatMessageYP(text); } filenameIdsResyncing.Remove(filenameId); } internal void CancelCurrentProcess() { if (boomboxAudioAction != null && boomboxAudioAction.actionState == ACTION_STATE.PROCESSING) { boomboxAudioAction.KillProcess(); YPlayCorePatch.AddChatMessageYP("Previous process cancelled " + GetFilenameIdString(boomboxAudioAction.filenameId)); } } internal void KillRequestId(int requestId) { if (boomboxAudioAction != null && boomboxAudioAction.requestId == requestId) { CancelCurrentProcess(); } } internal async Task DownloadMetadata(BoomboxRequestMetadata boomboxRequestMetadata, string url, string filenameId, float time) { await Task.Run(delegate { RM_STATUS rM_STATUS = RM_STATUS.NONE; if (string.IsNullOrEmpty(url?.Trim()) || string.IsNullOrEmpty(filenameId?.Trim())) { rM_STATUS = RM_STATUS.INVALID_METADATA; } else if (!YPlay.IsYPlayUtilValid()) { rM_STATUS = RM_STATUS.MISSING_DEPENDENCY; } else if (YPlay.IsDownloadingTools()) { rM_STATUS = RM_STATUS.DOWNLOADING_TOOLS; } else if (!YPlay.IsToolsExistAndNonEmpty()) { rM_STATUS = RM_STATUS.INVALID_TOOLS; } if (rM_STATUS != 0) { boomboxRequestMetadata.rmStatus = rM_STATUS; } else { string text = (audioIdTitles.ContainsKey(filenameId) ? audioIdTitles[filenameId] : null); int num = (audioIdDurations.ContainsKey(filenameId) ? audioIdDurations[filenameId] : 0); if (!IsMetadataLoadedForFilenameId(filenameId)) { (text, num) = GetAudioTitleDuration(url); if (string.IsNullOrEmpty(text?.Trim()) || num == 0) { boomboxRequestMetadata.rmStatus = RM_STATUS.INVALID_METADATA; return; } audioIdTitles[filenameId] = text; audioIdDurations[filenameId] = num; } int num2 = num / 60; if (num2 > 12) { boomboxRequestMetadata.rmStatus = RM_STATUS.INVALID_MAX_DURATION; } else if (string.IsNullOrEmpty(text?.Trim()) || num == 0) { boomboxRequestMetadata.rmStatus = RM_STATUS.INVALID_METADATA; } else { boomboxRequestMetadata.filenameId = filenameId; boomboxRequestMetadata.url = url; boomboxRequestMetadata.time = time; boomboxRequestMetadata.title = text; boomboxRequestMetadata.duration = num; if (boomboxRequestMetadata.rmStatus != RM_STATUS.CANCELLED) { boomboxRequestMetadata.rmStatus = RM_STATUS.VALID; } } } }); } private (string title, int duration) GetAudioTitleDuration(string url) { YoutubeDL val = YPlay.NewYoutubeDl(); string text = ""; int item = 0; try { OptionSet val2 = optionSet; RunResult<VideoData> result = val.RunVideoDataFetch(url, default(CancellationToken), true, false, val2).GetAwaiter().GetResult(); VideoData data = result.Data; if (result != null) { text = data.Title; item = (int)data.Duration.GetValueOrDefault(); } } catch (Exception) { return ("", 0); } if (string.IsNullOrEmpty(text?.Trim())) { text = GetFilenameIdFromUrl(url); } return (text, item); } internal POST_TASK LoadFile(string filenameId, string outputFileLocation, int requestId, bool resync) { if (IsFilenameLoaded(filenameId)) { boomboxAudioLoader.Start(boomboxAudioLoader.GetAudioClip(<boomboxItemController>P, requestId, outputFileLocation, resync)); return POST_TASK.NONE; } return POST_TASK.ERROR_LOADING_AUDIO; } private bool IsFilenameLoaded(string filenameId) { if (!string.IsNullOrEmpty(filenameId?.Trim())) { if (!IsFilenameIdDownloaded(filenameId)) { return BoomboxAudioLoader.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 (!string.IsNullOrEmpty(text?.Trim())) { return text; } return null; } internal static void KillAllBoomboxDownloaderProcesses() { foreach (KeyValuePair<ulong, BoomboxItemController> item in new Dictionary<ulong, BoomboxItemController>(BoomboxItemController.boomboxItemControllers)) { BoomboxItemController value = item.Value; value.boomboxAudioDownloader.CancelCurrentProcess(); } } internal static string GetOutputFileLocationWithoutExtensionForId(string id) { return YPlay.audioDirectory + "\\" + id; } internal static string GetOutputFileLocationTempForId(string id) { return GetOutputFileLocationWithoutExtensionForId(id) + ".part"; } internal static string GetOutputFileLocationForId(string id) { return GetOutputFileLocationWithoutExtensionForId(id) + "." + audioTypeExtension; } internal static string GetFilenameIdString(string filenameId) { if (string.IsNullOrEmpty(filenameId?.Trim())) { return null; } return "[" + filenameId + "]"; } } internal class BoomboxAudioAction { internal ACTION_STATE actionState; private readonly BoomboxAudioDownloader boomboxAudioDownloader; 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; private static readonly OptionSet optionSet; internal BoomboxAudioAction(BoomboxAudioDownloader boomboxAudioDownloader, int requestId, string filenameId, string outputFileLocation, string url) { this.boomboxAudioDownloader = boomboxAudioDownloader; this.requestId = requestId; this.filenameId = filenameId; this.outputFileLocation = outputFileLocation; this.url = url; tmpFile = YPlay.GetRandomTempFileLocation(); tmpFileWithExt = tmpFile + "." + BoomboxAudioDownloader.audioTypeExtension; youtubeDL = YPlay.NewYoutubeDl(); youtubeDL.OutputFileTemplate = tmpFile; cancellationTokenSource = new CancellationTokenSource(); } internal POST_TASK Start(bool resync) { YPlayCorePatch.AddChatMessageYP("Downloading " + BoomboxAudioDownloader.GetFilenameIdString(filenameId) + "..."); try { RunResult<string> result = youtubeDL.RunAudioDownload(url, (AudioConversionFormat)(BoomboxAudioDownloader.audioTypeExtension.Equals("wav") ? 7 : 3), cancellationTokenSource.Token, (IProgress<DownloadProgress>)null, (IProgress<string>)null, optionSet).GetAwaiter().GetResult(); } catch (Exception) { } try { if (actionState == ACTION_STATE.PROCESSING && boomboxAudioDownloader.lastDownloadRequestId == requestId) { if (!File.Exists(outputFileLocation)) { if (!BoomboxAudioDownloader.IsFileValid(tmpFileWithExt)) { throw new Exception("Temp file not valid"); } YPlay.CreateParentDirectory(outputFileLocation); File.Move(tmpFileWithExt, outputFileLocation); } actionState = ACTION_STATE.FINISHED; return boomboxAudioDownloader.LoadFile(filenameId, outputFileLocation, requestId, resync); } } catch (Exception) { KillProcess(); return POST_TASK.ERROR_DOWNLOADING_AUDIO; } finally { DeleteRequestFiles(); } return POST_TASK.NONE; } internal void KillProcess() { if (actionState == ACTION_STATE.PROCESSING) { actionState = ACTION_STATE.KILLED; try { cancellationTokenSource?.Cancel(); } catch (Exception) { } } DeleteRequestFiles(); } private void DeleteRequestFiles() { Task.Delay(2000).ContinueWith(delegate { YPlay.DeleteFile(tmpFile); YPlay.DeleteFile(tmpFileWithExt); }); } static BoomboxAudioAction() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown OptionSet val = new OptionSet(); val.NoPlaylist = true; val.ForceIPv4 = true; val.Format = "140"; val.PostprocessorArgs = MultiValue<string>.op_Implicit(new string[1] { "ffmpeg:-filter:a dynaudnorm" }); optionSet = val; } } internal class BoomboxItemController : NetworkBehaviour { internal static readonly Dictionary<ulong, BoomboxItemController> boomboxItemControllers = new Dictionary<ulong, BoomboxItemController>(); private static readonly Dictionary<AudioClip, BoomboxItemController> audioClipBoomboxItemController = new Dictionary<AudioClip, BoomboxItemController>(); private static readonly Dictionary<ulong, double> clientIdsLastRequestSentMs = new Dictionary<ulong, double>(); private double lastRequestSentMs; internal BoomboxAudioDownloader boomboxAudioDownloader; internal BoomboxItem boomboxItem; internal string serverFilenameId; internal string serverUrl; internal string serverTitle; internal int serverDuration; internal float serverTime; internal string filenameId; private string url; private string title; private int duration; private float timeSaved; private float timeRequested; internal AudioType audioType = (AudioType)13; private bool showSyncRandomBoomboxColorMsg; private COLOR_PATTERN colorPattern; private IEnumerator colorPatternCoroutine; internal BoomboxRequestMetadata boomboxRequestMetadata; private CancellationTokenSource metadataCompletionCancellationTokenSource; private CancellationTokenSource requestCompletionCancellationTokenSource; private static readonly DateTime epochDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 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 void Awake() { boomboxAudioDownloader = new BoomboxAudioDownloader(this); boomboxItem = ((Component)this).GetComponent<BoomboxItem>(); ((GrabbableObject)boomboxItem).itemProperties.requiresBattery = false; } internal void Start() { ulong networkObjectId = ((NetworkBehaviour)boomboxItem).NetworkObjectId; boomboxItemControllers[networkObjectId] = this; if (Config.configEntryRandomColor.Value && IsHostOrIsOffline()) { SyncRandomBoomboxColor(((NetworkBehaviour)this).NetworkManager.LocalClientId); } } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); } internal void SendRequestServerDelegate(string url, float time) { //IL_0015: 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) if (YPlayCorePatch.IsOfflineMode()) { SendRequestServerLocal(url, time); } else { SendRequestServerRpc(url, time); } } internal void SendBoomboxLoadedServerDelegate(int requestId, bool loaded, bool resync, RLE_REASON rleReason = RLE_REASON.NONE) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (YPlayCorePatch.IsOfflineMode()) { SendBoomboxLoadedServerLocal(requestId, loaded, resync, rleReason); } else { SendBoomboxLoadedServerRpc(requestId, loaded, resync, rleReason); } } internal void SyncBoomboxVolumeRequestServerDelegate(float volume, bool msg = false) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (YPlayCorePatch.IsOfflineMode()) { SyncBoomboxVolumeRequestClientShared(volume, YPlayCorePatch.LocalPlayerController.actualClientId, msg); } else { SyncBoomboxVolumeRequestServerRpc(volume, msg); } } internal void SyncBoomboxColorRequestServerDelegate(float r, float g, float b, COLOR_PATTERN colorPattern = COLOR_PATTERN.NONE) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (YPlayCorePatch.IsOfflineMode()) { if (!ApplyColorPattern(colorPattern, ((NetworkBehaviour)this).NetworkManager.LocalClientId)) { SyncBoomboxColorRequestClientShared(r, g, b, colorPattern, YPlayCorePatch.LocalPlayerController.actualClientId, msg: true); } } else { SyncBoomboxColorRequestServerRpc(r, g, b, colorPattern); } } internal void ResetBoomboxRequestServerDelegate() { if (YPlayCorePatch.IsOfflineMode()) { ResetBoombox(); } else { ResetBoomboxRequestServerRpc(); } } internal void SyncBoomboxTimeRequestServerDelegate(float time, REQUEST_TYPE requestType = REQUEST_TYPE.NONE) { //IL_0015: 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) if (YPlayCorePatch.IsOfflineMode()) { SyncBoomboxTimeRequestServerLocal(time, requestType); } else { SyncBoomboxTimeRequestServerRpc(time, requestType); } } internal void SyncBoomboxRequestLookingAtServerDelegate(ulong boomboxLookingAtId) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (YPlayCorePatch.IsOfflineMode()) { SyncBoomboxRequestLookingAtServerLocal(boomboxLookingAtId); } else { SyncBoomboxRequestLookingAtServerRpc(boomboxLookingAtId); } } private void SyncRandomBoomboxColor(ulong clientId, bool msg = false) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Color randomBoomboxColor = GetRandomBoomboxColor(); if (((NetworkBehaviour)this).IsHost) { SyncBoomboxColorRequestClientRpc(randomBoomboxColor.r, randomBoomboxColor.g, randomBoomboxColor.b, colorPattern, clientId, msg); } else { SyncBoomboxColorRequestClientShared(randomBoomboxColor.r, randomBoomboxColor.g, randomBoomboxColor.b, colorPattern, clientId, msg); } } [ServerRpc(RequireOwnership = false)] internal void SendRequestServerRpc(string url, float time, 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_0088: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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) //IL_022a: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3425911769u, serverRpcParams, (RpcDelivery)0); bool flag = url != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(url, false); } ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref time, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 3425911769u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost) || IsInvalidServerCall()) { return; } ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (ClientRequestWait(senderClientId)) { return; } ClientRpcParams clientRpcParams = default(ClientRpcParams); clientRpcParams.Send.TargetClientIds = new <>z__ReadOnlySingleElementList<ulong>(senderClientId); RM_STATUS rM_STATUS = RM_STATUS.NONE; string filenameIdFromUrl = BoomboxAudioDownloader.GetFilenameIdFromUrl(url); if (string.IsNullOrEmpty(url?.Trim()) || string.IsNullOrEmpty(filenameIdFromUrl?.Trim())) { rM_STATUS = RM_STATUS.INVALID_URL; } else if (!IsBoomboxValid(boomboxItem)) { rM_STATUS = RM_STATUS.INVALID_BOOMBOX; } else if (!YPlay.IsYPlayUtilValid()) { rM_STATUS = RM_STATUS.MISSING_DEPENDENCY; } else if (YPlay.IsDownloadingTools()) { rM_STATUS = RM_STATUS.DOWNLOADING_TOOLS; } else if (!YPlay.IsToolsExistAndNonEmpty()) { rM_STATUS = RM_STATUS.INVALID_TOOLS; } if (rM_STATUS != 0) { if (senderClientId != YPlayCorePatch.LocalPlayerController.actualClientId) { string text = rM_STATUS switch { RM_STATUS.MISSING_DEPENDENCY => "you are missing a dependency, please try reinstalling YPlayBoombox", RM_STATUS.DOWNLOADING_TOOLS => "you are still downloading tools", RM_STATUS.INVALID_TOOLS => "you have invalid tools, please try /yp reset-tools", _ => null, }; if (text != null) { string text2 = "You cannot process this client request because " + text; YPlay.LogError(text2); YPlayCorePatch.AddChatMessageYP(text2); } } SendRequestFailedClientRpc(filenameIdFromUrl, rM_STATUS, clientRpcParams); } else { if (boomboxRequestMetadata != null && boomboxRequestMetadata.rmStatus == RM_STATUS.INITIALIZING) { CancelBoomboxRequestServer(boomboxRequestMetadata.requestId, boomboxRequestMetadata.filenameId, senderClientId, RC_REASON.NEW_REQUEST); } DownloadMetadataServer(url, filenameIdFromUrl, time, senderClientId); } } [ServerRpc(RequireOwnership = false)] internal void SendBoomboxLoadedServerRpc(int requestId, bool loaded, bool resync, RLE_REASON rleReason = RLE_REASON.NONE, 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_008a: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1074417815u, serverRpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, requestId); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref loaded, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref resync, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<RLE_REASON>(ref rleReason, default(ForEnums)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 1074417815u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost) || IsInvalidServerCall()) { return; } ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (resync && loaded) { SyncBoomboxRequestVerifyMultipleServer(resync, senderClientId); } else if (IsBoomboxRequestMetadataActive(boomboxRequestMetadata)) { RC_REASON rC_REASON = RcReasonErrorCheck(); if (rC_REASON != 0) { CancelBoomboxRequestServer(requestId, boomboxRequestMetadata.filenameId, senderClientId, rC_REASON); } else { SendBoomboxLoadedCallServer(boomboxRequestMetadata, senderClientId, loaded, rleReason); } } } [ServerRpc(RequireOwnership = false)] internal void ResetBoomboxRequestServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2681523663u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2681523663u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !IsInvalidServerCall() && IsBoomboxValid(boomboxItem)) { ResetBoomboxRequestClientRpc(); } } } [ServerRpc(RequireOwnership = false)] internal void SyncBoomboxRequestLookingAtServerRpc(ulong boomboxLookingAtId, 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_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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3702246251u, serverRpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, boomboxLookingAtId); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 3702246251u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !IsInvalidServerCall() && boomboxItemControllers.ContainsKey(boomboxLookingAtId)) { BoomboxItemController boomboxItemController = boomboxItemControllers[boomboxLookingAtId]; BoomboxItem val2 = boomboxItemController.boomboxItem; if (IsBoomboxValid(val2) && ShouldResync(boomboxItemController)) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; SyncBoomboxRequestLookingAtClientRpc(boomboxLookingAtId, senderClientId); } } } [ServerRpc(RequireOwnership = false)] internal void SyncBoomboxTimeRequestServerRpc(float time, REQUEST_TYPE requestType = REQUEST_TYPE.NONE, 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2185615963u, serverRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref time, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<REQUEST_TYPE>(ref requestType, default(ForEnums)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 2185615963u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !IsInvalidServerCall() && IsBoomboxValid(boomboxItem) && IsBoomboxTimeValid(time) && ShouldResyncTime(time)) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; SyncBoomboxTimeRequestClientRpc(time, senderClientId, filenameId, requestType); } } } [ServerRpc(RequireOwnership = false)] internal void SyncBoomboxVolumeRequestServerRpc(float volume, bool msg, 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(160244116u, serverRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref volume, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref msg, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 160244116u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !IsInvalidServerCall() && IsBoomboxValid(boomboxItem)) { volume = Mathf.Clamp((float)Math.Round(volume, 1), 0f, 1f); if (ShouldResyncVolume(volume)) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; SyncBoomboxVolumeRequestClientRpc(volume, senderClientId, msg); } } } [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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3044477801u, 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, 3044477801u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !IsInvalidServerCall()) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (!ApplyColorPattern(colorPattern, senderClientId)) { SyncBoomboxColorRequestClientRpc(r, g, b, colorPattern, senderClientId, msg: true); } } } private bool ApplyColorPattern(COLOR_PATTERN colorPattern, ulong clientId) { this.colorPattern = colorPattern; if (colorPatternCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(colorPatternCoroutine); } if (this.colorPattern == COLOR_PATTERN.RAINBOW) { ((MonoBehaviour)this).StartCoroutine(colorPatternCoroutine = ColorPatternRainbow(clientId)); return true; } return false; } private IEnumerator ColorPatternRainbow(ulong clientId) { showSyncRandomBoomboxColorMsg = true; while (colorPattern == COLOR_PATTERN.RAINBOW) { SyncRandomBoomboxColor(clientId, showSyncRandomBoomboxColorMsg); showSyncRandomBoomboxColorMsg = false; yield return (object)new WaitForSeconds(1f); } } [ServerRpc(RequireOwnership = false)] internal void SyncAllBoomboxRequestServerRpc(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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1929840421u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, clientId); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1929840421u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !IsInvalidServerCall() && IsBoomboxValid(boomboxItem)) { ulong networkObjectId = ((NetworkBehaviour)boomboxItem).NetworkObjectId; BoomboxRequest boomboxRequest = GetBoomboxRequest(networkObjectId, request: true); if (boomboxRequest != null) { ClientRpcParams clientRpcParams = default(ClientRpcParams); clientRpcParams.Send.TargetClientIds = new <>z__ReadOnlySingleElementList<ulong>(clientId); SyncBoomboxVolumeRequestClientRpc(boomboxRequest.volume, 0uL, msg: false, clientRpcParams); Color boomboxBodyColor = GetBoomboxBodyColor(); SyncBoomboxColorRequestClientRpc(boomboxBodyColor.r, boomboxBodyColor.g, boomboxBodyColor.b, colorPattern, 0uL, msg: false, clientRpcParams); SyncBoomboxPlayingRequestClientRpc(boomboxRequest.filenameId, boomboxRequest.url, boomboxRequest.title, boomboxRequest.duration, boomboxRequest.time, boomboxRequest.isPlayingMusic, clientRpcParams); } } } private bool ClientRequestWait(ulong clientId) { //IL_005a: 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) double timeMs = GetTimeMs(); double val = 0.0; if (clientIdsLastRequestSentMs.ContainsKey(clientId)) { val = clientIdsLastRequestSentMs[clientId]; } else { clientIdsLastRequestSentMs[clientId] = timeMs; } double val2 = lastRequestSentMs; double num = Math.Max(val, val2); double num2 = timeMs - num; if (num2 <= 5000.0) { ClientRpcParams clientRpcParams = default(ClientRpcParams); clientRpcParams.Send.TargetClientIds = new <>z__ReadOnlySingleElementList<ulong>(clientId); double waitMs = Math.Max(0.0, 5000.0 - num2); SendRequestFailedWaitClientRpc(waitMs, clientRpcParams); return true; } clientIdsLastRequestSentMs[clientId] = (lastRequestSentMs = timeMs); return false; } private void SyncBoomboxRequestVerifyMultipleServer(bool resync = false, ulong clientId = 0uL) { //IL_008c: 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_0122: Unknown result type (might be due to invalid IL or missing references) if (IsInvalidServerCall()) { return; } Dictionary<ulong, BoomboxItemController> dictionary = new Dictionary<ulong, BoomboxItemController>(boomboxItemControllers); List<BoomboxItemController> list = new List<BoomboxItemController>(); foreach (KeyValuePair<ulong, BoomboxItemController> item in dictionary) { BoomboxItemController value = item.Value; if (!((Object)(object)value == (Object)null) && (resync || !((Object)(object)value == (Object)(object)this)) && !(value.filenameId != filenameId)) { list.Add(value); } } if (list.Count == 0) { return; } ClientRpcParams clientRpcParams = default(ClientRpcParams); if (resync) { clientRpcParams.Send.TargetClientIds = new <>z__ReadOnlySingleElementList<ulong>(clientId); } foreach (BoomboxItemController item2 in list) { ulong networkObjectId = ((NetworkBehaviour)item2).NetworkObjectId; BoomboxRequest boomboxRequest = item2.GetBoomboxRequest(networkObjectId); if (boomboxRequest != null) { item2.SyncBoomboxRequestVerifyMultipleClientRpc(boomboxRequest.filenameId, boomboxRequest.url, boomboxRequest.title, boomboxRequest.duration, boomboxRequest.time, boomboxRequest.isPlayingMusic, clientRpcParams); } } if (resync) { SendResyncedMessageClientRpc(clientRpcParams); } } internal void SendBoomboxLoadedCallServer(BoomboxRequestMetadata boomboxRequestMetadata, ulong clientId, bool loaded, RLE_REASON rleReason = RLE_REASON.NONE) { if (IsInvalidServerCall() || !IsBoomboxRequestMetadataActive(boomboxRequestMetadata) || !boomboxRequestMetadata.pendingClientIdRequests.Contains(clientId)) { return; } boomboxRequestMetadata.pendingClientIdRequests.Remove(clientId); int count = boomboxRequestMetadata.originalClientIdRequests.Count; int count2 = boomboxRequestMetadata.pendingClientIdRequests.Count; int loadedClientCount = Mathf.Clamp(count - count2, 0, count); SendBoomboxLoadedClientRpc(boomboxRequestMetadata.requestId, boomboxRequestMetadata.filenameId, clientId, loaded, loadedClientCount, count, rleReason); if (!loaded && clientId == YPlayCorePatch.LocalPlayerController.actualClientId) { CancelBoomboxRequestServer(boomboxRequestMetadata.requestId, boomboxRequestMetadata.filenameId, clientId, RC_REASON.HOST_FAILED); } else if (count2 == 0) { boomboxRequestMetadata.pendingClientIdRequests.Clear(); ulong networkObjectId = ((NetworkBehaviour)boomboxItem).NetworkObjectId; BoomboxRequest boomboxRequest = GetBoomboxRequest(networkObjectId, request: true); if (boomboxRequest != null) { boomboxRequest.filenameId = boomboxRequestMetadata.filenameId; boomboxRequest.url = boomboxRequestMetadata.url; boomboxRequest.title = boomboxRequestMetadata.title; boomboxRequest.duration = boomboxRequestMetadata.duration; boomboxRequest.time = boomboxRequestMetadata.time; SyncBoomboxRequestClientRpc(request: true, boomboxRequest.filenameId, boomboxRequest.url, boomboxRequest.title, boomboxRequest.duration, boomboxRequest.time, boomboxRequest.isPlayingMusic); SyncBoomboxRequestVerifyMultipleServer(resync: false, 0uL); } } } private async void DownloadMetadataServer(string url, string filenameId, float time, ulong clientId) { if (IsInvalidServerCall()) { return; } SendRequestInitialisingMessageClientRpc(clientId, filenameId); if (boomboxRequestMetadata != null) { KillRequestIdClientRpc(boomboxRequestMetadata.requestId); } CancelMetadataAndRequestTimersShared(); HashSet<ulong> collection = new HashSet<ulong>(YPlayCorePatch.modEnabledForClientIds); BoomboxRequestMetadata boomboxRequestMetadataLocal = (boomboxRequestMetadata = new BoomboxRequestMetadata { originalClientIdRequests = new HashSet<ulong>(collection), pendingClientIdRequests = new HashSet<ulong>(collection) }); CancellationTokenSource metadataCompletionCancellationTokenSourceLocal = (metadataCompletionCancellationTokenSource = new CancellationTokenSource()); Task metadataTask = boomboxAudioDownloader.DownloadMetadata(boomboxRequestMetadataLocal, url, filenameId, time); if (await Task.WhenAny(new Task[2] { metadataTask, Task.Delay(15000, metadataCompletionCancellationTokenSourceLocal.Token) }) != metadataTask) { if (metadataCompletionCancellationTokenSourceLocal.IsCancellationRequested || !IsBoomboxRequestMetadataActive(boomboxRequestMetadataLocal)) { return; } SendRequestFailedClientRpc(filenameId, boomboxRequestMetadataLocal.rmStatus = RM_STATUS.TIMEOUT); } if (boomboxRequestMetadataLocal.rmStatus != RM_STATUS.VALID) { SendRequestFailedClientRpc(filenameId, boomboxRequestMetadataLocal.rmStatus); return; } DownloadTaskClientRpc(boomboxRequestMetadataLocal.requestId, boomboxRequestMetadataLocal.filenameId, boomboxRequestMetadataLocal.title, boomboxRequestMetadataLocal.duration, boomboxRequestMetadataLocal.url, time); CancellationTokenSource requestCompletionCancellationTokenSourceLocal = (requestCompletionCancellationTokenSource = new CancellationTokenSource()); Task requestCompletionTimeoutTask = RequestCompletionTimeoutTask(45000); if (await Task.WhenAny(new Task[2] { requestCompletionTimeoutTask, Task.Delay(45000, requestCompletionCancellationTokenSourceLocal.Token) }) == requestCompletionTimeoutTask || requestCompletionCancellationTokenSourceLocal.IsCancellationRequested || !IsBoomboxRequestMetadataActive(boomboxRequestMetadataLocal)) { return; } ulong actualClientId = YPlayCorePatch.LocalPlayerController.actualClientId; HashSet<ulong> hashSet = new HashSet<ulong>(); foreach (ulong pendingClientIdRequest in boomboxRequestMetadataLocal.pendingClientIdRequests) { hashSet.Add(pendingClientIdRequest); } HashSet<ulong> hashSet2 = hashSet; if (hashSet2.Contains(YPlayCorePatch.LocalPlayerController.actualClientId)) { hashSet2 = new HashSet<ulong> { actualClientId }; } foreach (ulong item in hashSet2) { SendBoomboxLoadedCallServer(boomboxRequestMetadataLocal, item, loaded: false, RLE_REASON.TIMEOUT); } } private async Task RequestCompletionTimeoutTask(int timeout) { await Task.Run(delegate { Thread.Sleep(timeout); }); } private void CancelBoomboxRequestServer(int requestId, string filenameId, ulong clientId, RC_REASON rcReason) { if (!IsInvalidServerCall()) { CancelBoomboxServer(requestId); SendBoomboxRequestCancelledMessageClientRpc(filenameId, clientId, rcReason); } } private void CancelBoomboxServer(int requestId) { if (!IsInvalidServerCall()) { if (boomboxRequestMetadata != null && boomboxRequestMetadata.requestId == requestId) { boomboxRequestMetadata.rmStatus = RM_STATUS.CANCELLED; boomboxRequestMetadata.pendingClientIdRequests.Clear(); CancelRequestTimerShared(); } ClearPreviousAudioClipsClientRpc(); } } public override void OnDestroy() { if (!IsInvalidServerCall()) { if (boomboxRequestMetadata != null) { CancelBoomboxServer(boomboxRequestMetadata.requestId); } ((NetworkBehaviour)this).OnDestroy(); } } [ClientRpc] private void KillRequestIdClientRpc(int requestId) { //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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3126721376u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, requestId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3126721376u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { boomboxAudioDownloader.KillRequestId(requestId); } } } [ClientRpc] private void ClearPreviousAudioClipsClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3187082761u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3187082761u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { ClearUnusedAudioClips(); } } } [ClientRpc] private void SyncBoomboxRequestLookingAtClientRpc(ulong boomboxLookingAtId, 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3898947593u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, boomboxLookingAtId); BytePacker.WriteValueBitPacked(val2, clientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3898947593u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SyncBoomboxRequestLookingAtClientShared(boomboxLookingAtId, clientId); } } } [ClientRpc] private void SendRequestInitialisingMessageClientRpc(ulong clientId, string filenameId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0095: 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_00c7: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2497770173u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, clientId); bool flag = filenameId != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(filenameId, false); } ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2497770173u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { string playerUsernameFromClientId = YPlayCorePatch.GetPlayerUsernameFromClientId(clientId); YPlayCorePatch.AddChatMessageYP(playerUsernameFromClientId + " requested [" + filenameId + "]..."); } } [ClientRpc] private void SendResyncedMessageClientRpc(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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3136043952u, clientRpcParams, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 3136043952u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { YPlayCorePatch.AddChatMessageYP("Resync successful"); } } } [ClientRpc] private void DownloadTaskClientRpc(int requestId, string filenameId, string title, int duration, string url, float time) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_0095: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(923605557u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, requestId); bool flag = filenameId != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(filenameId, false); } bool flag2 = title != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives)); if (flag2) { ((FastBufferWriter)(ref val2)).WriteValueSafe(title, false); } BytePacker.WriteValueBitPacked(val2, duration); bool flag3 = url != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag3, default(ForPrimitives)); if (flag3) { ((FastBufferWriter)(ref val2)).WriteValueSafe(url, false); } ((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref time, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 923605557u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { DownloadTaskClientShared(requestId, filenameId, title, duration, url, time); } } [ClientRpc] private void SendRequestFailedClientRpc(string filenameId, RM_STATUS rmStatus, 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_0088: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2668383935u, clientRpcParams, (RpcDelivery)0); bool flag = filenameId != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(filenameId, false); } ((FastBufferWriter)(ref val)).WriteValueSafe<RM_STATUS>(ref rmStatus, default(ForEnums)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2668383935u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SendRequestFailedClientShared(filenameId, rmStatus); } } [ClientRpc] private void SendRequestFailedWaitClientRpc(double waitMs, 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_0097: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(115722075u, clientRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref waitMs, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 115722075u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { int num = Math.Max(1, (int)Math.Ceiling(TimeSpan.FromMilliseconds(waitMs).TotalSeconds)); YPlayCorePatch.AddChatMessageYP(string.Format("Please wait {0} second{1} before calling this command", num, (num == 1) ? null : "s")); } } } [ClientRpc] private void SendBoomboxRequestCancelledMessageClientRpc(string filenameId, ulong clientId, RC_REASON rcReason) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0088: 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_00af: 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_00ce: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4201653590u, val, (RpcDelivery)0); bool flag = filenameId != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(filenameId, false); } BytePacker.WriteValueBitPacked(val2, clientId); ((FastBufferWriter)(ref val2)).WriteValueSafe<RC_REASON>(ref rcReason, default(ForEnums)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4201653590u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SendBoomboxRequestCancelledMessageClientShared(filenameId, rcReason); } } [ClientRpc] private void SendBoomboxLoadedClientRpc(int requestId, string filenameId, ulong clientId, bool loaded, int loadedClientCount, int originalRequestCount, RLE_REASON rleReason) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_0095: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e4: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3390314703u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, requestId); bool flag = filenameId != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(filenameId, false); } BytePacker.WriteValueBitPacked(val2, clientId); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref loaded, default(ForPrimitives)); BytePacker.WriteValueBitPacked(val2, loadedClientCount); BytePacker.WriteValueBitPacked(val2, originalRequestCount); ((FastBufferWriter)(ref val2)).WriteValueSafe<RLE_REASON>(ref rleReason, default(ForEnums)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3390314703u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SendBoomboxLoadedClientShared(requestId, filenameId, clientId, loaded, loadedClientCount, originalRequestCount, rleReason); } } [ClientRpc] private void ResetBoomboxRequestClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3381308416u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3381308416u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { ResetBoombox(); } } } [ClientRpc] private void SyncBoomboxRequestClientRpc(bool request, string filenameId, string url, string title, int duration, float time, bool isPlayingMusic) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_00a3: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0194: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3399703514u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref request, default(ForPrimitives)); bool flag = filenameId != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(filenameId, false); } bool flag2 = url != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives)); if (flag2) { ((FastBufferWriter)(ref val2)).WriteValueSafe(url, false); } bool flag3 = title != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag3, default(ForPrimitives)); if (flag3) { ((FastBufferWriter)(ref val2)).WriteValueSafe(title, false); } BytePacker.WriteValueBitPacked(val2, duration); ((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref time, default(ForPrimitives)); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isPlayingMusic, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3399703514u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SyncBoomboxRequestClientShared(request, filenameId, url, title, duration, time, isPlayingMusic); } } [ClientRpc] private void SyncBoomboxRequestVerifyMultipleClientRpc(string filenameId, string url, string title, int duration, float time, bool isPlayingMusic, 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_0088: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1261714853u, clientRpcParams, (RpcDelivery)0); bool flag = filenameId != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(filenameId, false); } bool flag2 = url != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives)); if (flag2) { ((FastBufferWriter)(ref val)).WriteValueSafe(url, false); } bool flag3 = title != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag3, default(ForPrimitives)); if (flag3) { ((FastBufferWriter)(ref val)).WriteValueSafe(title, false); } BytePacker.WriteValueBitPacked(val, duration); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref time, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref isPlayingMusic, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1261714853u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall() && !(filenameId == this.filenameId)) { AudioClip audioClipFromFilenameId = GetAudioClipFromFilenameId(filenameId); SyncBoombox(request: false, filenameId, url, title, duration, time, audioClipFromFilenameId, isPlayingMusic, autoRequestPlayState: false); ClearUnusedAudioClips(); } } [ClientRpc] private void SyncBoomboxTimeRequestClientRpc(float time, ulong clientId, string filenameId, REQUEST_TYPE requestType) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1175447752u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref time, default(ForPrimitives)); BytePacker.WriteValueBitPacked(val2, clientId); bool flag = filenameId != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(filenameId, false); } ((FastBufferWriter)(ref val2)).WriteValueSafe<REQUEST_TYPE>(ref requestType, default(ForEnums)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1175447752u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SyncBoomboxTimeRequestClientShared(time, clientId, filenameId, requestType); } } [ClientRpc] internal void SyncBoomboxVolumeRequestClientRpc(float volume, 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1318585972u, clientRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref volume, default(ForPrimitives)); BytePacker.WriteValueBitPacked(val, clientId); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref msg, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1318585972u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SyncBoomboxVolumeRequestClientShared(volume, clientId, msg); } } } [ClientRpc] internal void SyncBoomboxColorRequestClientRpc(float r, float g, float b, COLOR_PATTERN colorPattern, 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3867183133u, 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)); BytePacker.WriteValueBitPacked(val, clientId); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref msg, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 3867183133u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall()) { SyncBoomboxColorRequestClientShared(r, g, b, colorPattern, clientId, msg); } } } [ClientRpc] internal void SyncBoomboxPlayingRequestClientRpc(string filenameId, string url, string title, int duration, float time, bool isPlayingMusic, 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_0088: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1911341357u, clientRpcParams, (RpcDelivery)0); bool flag = filenameId != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(filenameId, false); } bool flag2 = url != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives)); if (flag2) { ((FastBufferWriter)(ref val)).WriteValueSafe(url, false); } bool flag3 = title != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag3, default(ForPrimitives)); if (flag3) { ((FastBufferWriter)(ref val)).WriteValueSafe(title, false); } BytePacker.WriteValueBitPacked(val, duration); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref time, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref isPlayingMusic, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1911341357u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !IsInvalidClientCall() && IsBoomboxValid(boomboxItem)) { AudioClip audioClipFromFilenameId = GetAudioClipFromFilenameId(filenameId); if (!Object.op_Implicit((Object)(object)audioClipFromFilenameId)) { ResetAudioClip(); } SyncBoombox(request: false, filenameId, url, title, duration, time, audioClipFromFilenameId, isPlayingMusic && !boomboxItem.isPlayingMusic); } } internal void PlayBoombox(float forceTime = 0f) { if (!IsBoomboxValid(boomboxItem)) { return; } AudioClip clip = boomboxItem.boomboxAudio.clip; if (!Config.configEntrySync.Value && (Object)(object)clip != (Object)null) { if (audioClipBoomboxItemController.ContainsKey(clip)) { BoomboxItemController boomboxItemController = audioClipBoomboxItemController[clip]; if ((Object)(object)boomboxItemController != (Object)(object)this && IsBoomboxValid(boomboxItemController.boomboxItem) && !string.IsNullOrEmpty(filenameId?.Trim()) && boomboxItemController.filenameId == filenameId && boomboxItemController.boomboxItem.isPlayingMusic) { boomboxItemController.StopBoombox(); } } audioClipBoomboxItemController[clip] = this; } if (!IsAudioLoadedInMemory()) { boomboxItem.boomboxAudio.time = 0f; } else if (forceTime > 0f) { boomboxItem.boomboxAudio.time = forceTime; } else if (timeSaved > 0f) { boomboxItem.boomboxAudio.time = timeSaved; } boomboxItem.boomboxAudio.pitch = 1f; boomboxItem.boomboxAudio.Play(); boomboxItem.isPlayingMusic = (((GrabbableObject)boomboxItem).isBeingUsed = true); } internal void StopBoombox(float forceTime = 0f) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (IsBoomboxValid(boomboxItem)) { if (!IsAudioLoadedInMemory()) { boomboxItem.boomboxAudio.time = (timeSaved = 0f); } else if (forceTime > 0f) { boomboxItem.boomboxAudio.time = (timeSaved = forceTime); } else { timeSaved = boomboxItem.boomboxAudio.time; } if (((NetworkBehaviour)this).IsHost) { SyncBoomboxTimeRequestServerRpc(boomboxItem.boomboxAudio.time, REQUEST_TYPE.STOP); } bool isPlayingMusic = boomboxItem.is
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.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-2024 Bluegrams")] [assembly: AssemblyDescription("A 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.")] [assembly: AssemblyFileVersion("1.1.1.24278")] [assembly: AssemblyInformationalVersion("1.1.1+8863d5327ce0a6cf747b294977161b224c066434")] [assembly: AssemblyProduct("YPlayUtil")] [assembly: AssemblyTitle("YPlayUtil")] [assembly: AssemblyVersion("1.1.1.24278")] 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 static 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 HttpClient _client = new HttpClient(); 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 string YtDlpBinaryName => GetYtDlpBinaryName(); public static string FfmpegBinaryName => GetFfmpegBinaryName(); public static string FfprobeBinaryName => GetFfprobeBinaryName(); 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(string ytDlpReleaseDate, bool skipExisting = true, string directoryPath = "") { 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); } } else { await DownloadYtDlp(directoryPath); await DownloadFFmpeg(directoryPath); await DownloadFFprobe(directoryPath); } } private static string GetYtDlpDownloadUrl(string releaseDate) { string text = "https://github.com/yt-dlp/yt-dlp/releases/download/" + releaseDate + "/yt-dlp"; return OSHelper.GetOSVersion() switch { OSVersion.Windows => text + "_x86.exe", OSVersion.OSX => text + "_macos", OSVersion.Linux => text, _ => throw new Exception("Your OS isn't supported"), }; } private static string GetSevenZipDownloadUrl() { return "https://www.7-zip.org/a/7zr.exe"; } private static string GetFFmpegEssentialsDownloadUrl(string version, bool sevenZip) { return "https://github.com/GyanD/codexffmpeg/releases/download/" + version + "/ffmpeg-" + version + "-essentials_build." + (sevenZip ? "7z" : "zip"); } private static string GetYtDlpBinaryName() { string ytDlpDownloadUrl = GetYtDlpDownloadUrl(null); switch (OSHelper.GetOSVersion()) { case OSVersion.Windows: return "yt-dlp.exe"; case OSVersion.OSX: case OSVersion.Linux: return Path.GetFileName(ytDlpDownloadUrl); default: 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"); } } public static async Task DownloadYtDlp(string releaseDate, string directoryPath = "") { string ytDlpDownloadUrl = GetYtDlpDownloadUrl(releaseDate); if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } string downloadLocation = Path.Combine(directoryPath, GetYtDlpBinaryName()); File.WriteAllBytes(downloadLocation, await DownloadFileBytesAsync(ytDlpDownloadUrl)); } public static async Task DownloadFFmpeg(string version, string directoryPath = "") { await FFDownloader(version, directoryPath); } public static async Task DownloadFFprobe(string version, string directoryPath = "") { await FFDownloader(version, directoryPath, FFmpegApi.BinaryType.FFprobe); } public static async Task DownloadSevenZip(string path = "") { File.WriteAllBytes(path, await DownloadFileBytesAsync(GetSevenZipDownloadUrl())); } public static async Task DownloadFFmpegEssentials7zArchive(string version, string path = "") { File.WriteAllBytes(path, await DownloadFileBytesAsync(GetFFmpegEssentialsDownloadUrl(version, sevenZip: true))); } public static async Task DownloadFFmpegEssentials(string version, string directoryPath = "") { using MemoryStream stream = new MemoryStream(await DownloadFileBytesAsync(GetFFmpegEssentialsDownloadUrl(version, sevenZip: false))); using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read); if (zipArchive.Entries.Count <= 0) { return; } string ffmpegBinaryName = GetFfmpegBinaryName(); foreach (ZipArchiveEntry entry in zipArchive.Entries) { if (entry.Name.Equals(ffmpegBinaryName, StringComparison.OrdinalIgnoreCase)) { entry.ExtractToFile(Path.Combine(directoryPath, entry.Name), overwrite: true); break; } } } public static async Task Extract7z(string sevenZipExePath, string path, string workingDirectory = "") { await Task.Run(delegate { string ffmpegBinaryName = GetFfmpegBinaryName(); try { using Process process = new Process(); process.StartInfo.FileName = sevenZipExePath; process.StartInfo.UseShellExecute = false; process.StartInfo.Arguments = "e \"" + path + "\" *" + ffmpegBinaryName + " -r -aoa"; process.StartInfo.WorkingDirectory = workingDirectory; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.Start(); process.WaitForExit(); } catch (Exception) { } }); } public static async Task ExtractZip(string path, string workingDirectory = "") { await Task.Run(delegate { string ffmpegBinaryName = GetFfmpegBinaryName(); using ZipArchive zipArchive = ZipFile.OpenRead(path); foreach (ZipArchiveEntry entry in zipArchive.Entries) { if (entry.Name.Equals(ffmpegBinaryName, StringComparison.OrdinalIgnoreCase)) { entry.ExtractToFile(Path.Combine(workingDirectory, ffmpegBinaryName)); break; } } }); } private static async Task FFDownloader(string version, string directoryPath = "", FFmpegApi.BinaryType binary = FFmpegApi.BinaryType.FFmpeg) { if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } string requestUri = "https://ffbinaries.com/api/v1/version/" + version; FFmpegApi.Root root = JsonConvert.DeserializeObject<FFmpegApi.Root>(await (await _client.GetAsync(requestUri)).Content.ReadAsStringAsync()); 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"), }; using MemoryStream stream = new MemoryStream(await DownloadFileBytesAsync((binary == FFmpegApi.BinaryType.FFmpeg) ? osBinVersion.Ffmpeg : osBinVersion.Ffprobe)); using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read); if (zipArchive.Entries.Count > 0) { zipArchive.Entries[0].ExtractToFile(Path.Combine(directoryPath, zipArchive.Entries[0].FullName), overwrite: true); } } public static async Task<byte[]> DownloadFileBytesAsync(string uri) { if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri _)) { throw new InvalidOperationException("URI is invalid."); } return await _client.GetByteArrayAsync(uri); } 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), Exec = "echo outfile: {}" }; } 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 bool UseWindowsEncodingWorkaround { get; set; } = true; 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 (OSHelper.IsWindows && UseWindowsEncodingWorkaround) { processStartInfo.FileName = "cmd.exe"; string text = (string.IsNullOrEmpty(PythonPath) ? ("\"" + ExecutablePath + "\" " + ConvertToArgs(urls, options)) : ("\"" + PythonPath + "\" \"" + ExecutablePath + "\" " + ConvertToArgs(urls, options))); processStartInfo.Arguments = "/C chcp 65001 >nul 2>&1 && " + text; } else 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 stringValue = s.Substring(array[0].Length).Trim().Trim(new char[1] { '"' }); if (!OptionStrings.Contains(array[0])) { throw new ArgumentException("Given string does not match required format."); } T val = Utils.OptionValueFromString<T>(stringValue); 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 stringValue = s.Substring(array[0].Length).Trim().Trim(new char[1] { '"' }); if (!OptionStrings.Contains(array[0])) { throw new ArgumentException("Given string does not match required format."); } Value = Utils.OptionValueFromString<T>(stringValue); } 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 { 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> xattrSetFilesize = new Option<bool>("--xattr-set-filesize"); 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> dumpUserAgent = new Option<bool>("--dump-user-agent"); 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 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<string> alias = new MultiOption<string>("--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<string> replaceInMetadata = new MultiOption<string>("--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", "--convert-subtitles"); 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 XattrSetFilesize { get { return xattrSetFilesize.Value; } set { xattrSetFilesize.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 DumpUserAgent { get { return dumpUserAgent.Value; } set { dumpUserAgent.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 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<string> Alias { get { return alias.Value; } set { alias.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<string> 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 { yesPlaylist.Value = value; } } public byte? AgeLimit { get { return ageLimit.Value; } set { ageLimit.Value = value; } } public string DownloadArchive { get { return downloadArchive.Value; } set { downloadArchive.Value = value; } } public bool NoDownloadArchive { get { return noDownloadArchive.Value; } set { noDownloadArchive.Value = value; } } public int? MaxDownloads { get { return maxDownloads.Value; } set { maxDownloads.Value = value; } } public bool BreakOnExisting { get { return breakOnExisting.Value; } set { breakOnExisting.Value = value; } } public bool NoBreakOnExisting { get { return noBreakOnExisting.Value; } set { noBreakOnExisting.Value = value; } } public bool BreakPerInput { get { return breakPerInput.Value; } set { breakPerInput.Value = value; } } public bool NoBreakPerInput { get { return noBreakPerInput.Value; } set { noBreakPerInput.Value = value; } } public int? SkipPlaylistAfterErrors { get { return skipPlaylistAfterErrors.Value; } set { skipPlaylistAfterErrors.Value = value; } } public string Encoding { get { return encoding.Value; } set { encoding.Value = value; } } public bool LegacyServerConnect { get { return legacyServerConnect.Value; } set { legacyServerConnect.Value = value; } } public bool NoCheckCertificates { get { return noCheckCertificates.Value; } set { noCheckCertificates.Value = value; } } public bool PreferInsecure { get { return preferInsecure.Value; } set { preferInsecure.Value = value; } } public MultiValue<string> AddHeaders { get { return addHeaders.Value; } set { addHeaders.Value = value; } } public bool BidiWorkaround { get { return bidiWorkaround.Value; } set { bidiWorkaround.Value = value; } } public int? SleepRequests { get { return sleepRequests.Value; } set { sleepRequests.Value = value; } } public int? SleepInterval { get { return sleepInterval.Value; } set { sleepInterval.Value = value; } } public int? MaxSleepInterval { get { return maxSleepInterval.Value; } set { maxSleepInterval.Value = value; } } public int? SleepSubtitles { get { return sleepSubtitles.Value; } set { sleepSubtitles.Value = value; } } public void WriteConfigFile(string path) { File.WriteAllLines(path, GetOptionFlags()); } public override string ToString() { return " " + string.Join(" ", GetOptionFlags()); } public IEnumerable<string> GetOptionFlags() { return from value in GetKnownOptions().Concat(CustomOptions).SelectMany((IOption opt) => opt.ToStringCollection()) where !string.IsNullOrWhiteSpace(value) select value; } internal IEnumerable<IOption> GetKnownOptions() { return (from p in GetType().GetRuntimeFields() where p.FieldType.IsGenericType && p.FieldType.GetInterfaces().Contains(typeof(IOption)) select p.GetValue(this)).Cast<IOption>(); } public OptionSet OverrideOptions(OptionSet overrideOptions, bool forceOverride = false) { OptionSet optionSet = (OptionSet)Clone(); optionSet.CustomOptions = optionSet.CustomOptions.Concat(overrideOptions.CustomOptions).Distinct(Comparer).ToArray(); foreach (FieldInfo item in from p in overrideOptions.GetType().GetRuntimeFields() where p.FieldType.IsGenericType && p.FieldType.GetInterfaces().Contains(typeof(IOption)) select p) { IOption option = (IOption)item.GetValue(overrideOptions); if (forceOverride || option.IsSet) { optionSet.GetType().GetField(item.Name, BindingFlags.Instance | BindingFlags.NonPublic).SetValue(optionSet, option); } } return optionSet; } public static OptionSet FromString(IEnumerable<string> lines) { OptionSet optionSet = new OptionSet(); IOption[] customOptions = (from option in GetOptions(lines, optionSet.GetKnownOptions()) where option.IsCustom select option).ToArray(); optionSet.CustomOptions = customOptions; return optionSet; } private static IEnumerable<IOption> GetOptions(IEnumerable<string> lines, IEnumerable<IOption> options) { IEnumerable<IOption> knownOptions = options.ToList(); foreach (string line in lines) { string text = line.Trim(); if (!text.StartsWith("#") && !string.IsNullOrWhiteSpace(text)) { string[] array = text.Split(new char[1] { ' ' }); string flag = array[0]; IOption option = knownOptions.FirstOrDefault((IOption o) => o.OptionStrings.Contains(flag)); IOption option3; if (array.Length <= 1) { IOption option2 = new Option<bool>(true, flag); option3 = option2; } else { IOption option2 = new Option<string>(true, flag); option3 = option2; } IOption option4 = option3; IOption option5 = option ?? option4; option5.SetFromString(text); yield return option5; } } } public static OptionSet LoadConfigFile(string path) { return FromString(File.ReadAllLines(path)); } public object Clone() { return FromString(GetOptionFlags()); } public void AddCustomOption<T>(string optionString, T value) { Option<T> option = new Option<T>(true, optionString); option.Value = value; CustomOptio