Decompiled source of OOD LIB v1.0.5
Microsoft.Bcl.AsyncInterfaces.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyDefaultAlias("Microsoft.Bcl.AsyncInterfaces")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: AssemblyMetadata("IsAotCompatible", "True")] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("Provides the IAsyncEnumerable<T> and IAsyncDisposable interfaces and helper types for .NET Standard 2.0. This package is not required starting with .NET Standard 2.1 and .NET Core 3.0.")] [assembly: AssemblyFileVersion("10.0.125.57005")] [assembly: AssemblyInformationalVersion("10.0.1+fad253f51b461736dfd3cd9c15977bb7493becef")] [assembly: AssemblyProduct("Microsoft® .NET")] [assembly: AssemblyTitle("Microsoft.Bcl.AsyncInterfaces")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/dotnet")] [assembly: AssemblyVersion("10.0.0.1")] [module: RefSafetyRules(11)] [module: System.Runtime.CompilerServices.NullablePublicOnly(false)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class NullablePublicOnlyAttribute : Attribute { public readonly bool IncludesInternals; public NullablePublicOnlyAttribute(bool P_0) { IncludesInternals = P_0; } } [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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { public ExtensionMarkerAttribute(string name) { } } } namespace System { public interface IAsyncDisposable { ValueTask DisposeAsync(); } internal static class ExceptionPolyfills { [SpecialName] public sealed class <G>$E6188BA5B951F1F7AA9135E0EBB76F2B { [SpecialName] public static class <M>$96F0261AC622664B8B003966835C0332 { } [ExtensionMarker("<M>$96F0261AC622664B8B003966835C0332")] public static void ThrowIfNull([NotNull] object argument, [CallerArgumentExpression("argument")] string paramName = null) { throw null; } } [SpecialName] public sealed class <G>$3F30F31B33543D5FB8E174FB4FD780B9 { [SpecialName] public static class <M>$1F10CFA08738E6D8AF61CBECC6763DBC { } [ExtensionMarker("<M>$1F10CFA08738E6D8AF61CBECC6763DBC")] public static void ThrowIf([DoesNotReturnIf(true)] bool condition, object instance) { throw null; } [ExtensionMarker("<M>$1F10CFA08738E6D8AF61CBECC6763DBC")] public static void ThrowIf([DoesNotReturnIf(true)] bool condition, Type type) { throw null; } } public static void ThrowIfNull([NotNull] object argument, [CallerArgumentExpression("argument")] string paramName = null) { if (argument == null) { ThrowArgumentNullException(paramName); } } [DoesNotReturn] private static void ThrowArgumentNullException(string paramName) { throw new ArgumentNullException(paramName); } public static void ThrowIf([DoesNotReturnIf(true)] bool condition, object instance) { if (condition) { ThrowObjectDisposedException(instance); } } public static void ThrowIf([DoesNotReturnIf(true)] bool condition, Type type) { if (condition) { ThrowObjectDisposedException(type); } } [DoesNotReturn] private static void ThrowObjectDisposedException(object instance) { throw new ObjectDisposedException(instance?.GetType().FullName); } [DoesNotReturn] private static void ThrowObjectDisposedException(Type type) { throw new ObjectDisposedException(type?.FullName); } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Method, Inherited = false)] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace System.Collections.Generic { public interface IAsyncEnumerable<out T> { IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)); } public interface IAsyncEnumerator<out T> : IAsyncDisposable { T Current { get; } ValueTask<bool> MoveNextAsync(); } } namespace System.Runtime.InteropServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class LibraryImportAttribute : Attribute { public string LibraryName { get; } public string EntryPoint { get; set; } public StringMarshalling StringMarshalling { get; set; } public Type StringMarshallingCustomType { get; set; } public bool SetLastError { get; set; } public LibraryImportAttribute(string libraryName) { LibraryName = libraryName; } } internal enum StringMarshalling { Custom, Utf8, Utf16 } } namespace System.Runtime.CompilerServices { [StructLayout(LayoutKind.Auto)] public struct AsyncIteratorMethodBuilder { private AsyncTaskMethodBuilder _methodBuilder; private object _id; internal object ObjectIdForDebugger => _id ?? Interlocked.CompareExchange(ref _id, new object(), null) ?? _id; public static AsyncIteratorMethodBuilder Create() { AsyncIteratorMethodBuilder result = default(AsyncIteratorMethodBuilder); result._methodBuilder = AsyncTaskMethodBuilder.Create(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void MoveNext<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { _methodBuilder.Start(ref stateMachine); } public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine); } public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); } public void Complete() { _methodBuilder.SetResult(); } } [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] public sealed class AsyncIteratorStateMachineAttribute : StateMachineAttribute { public AsyncIteratorStateMachineAttribute(Type stateMachineType) : base(stateMachineType) { } } [StructLayout(LayoutKind.Auto)] public readonly struct ConfiguredAsyncDisposable { private readonly IAsyncDisposable _source; private readonly bool _continueOnCapturedContext; internal ConfiguredAsyncDisposable(IAsyncDisposable source, bool continueOnCapturedContext) { _source = source; _continueOnCapturedContext = continueOnCapturedContext; } public ConfiguredValueTaskAwaitable DisposeAsync() { return _source.DisposeAsync().ConfigureAwait(_continueOnCapturedContext); } } [StructLayout(LayoutKind.Auto)] public readonly struct ConfiguredCancelableAsyncEnumerable<T> { [StructLayout(LayoutKind.Auto)] public readonly struct Enumerator { private readonly IAsyncEnumerator<T> _enumerator; private readonly bool _continueOnCapturedContext; public T Current => _enumerator.Current; internal Enumerator(IAsyncEnumerator<T> enumerator, bool continueOnCapturedContext) { _enumerator = enumerator; _continueOnCapturedContext = continueOnCapturedContext; } public ConfiguredValueTaskAwaitable<bool> MoveNextAsync() { return _enumerator.MoveNextAsync().ConfigureAwait(_continueOnCapturedContext); } public ConfiguredValueTaskAwaitable DisposeAsync() { return _enumerator.DisposeAsync().ConfigureAwait(_continueOnCapturedContext); } } private readonly IAsyncEnumerable<T> _enumerable; private readonly CancellationToken _cancellationToken; private readonly bool _continueOnCapturedContext; internal ConfiguredCancelableAsyncEnumerable(IAsyncEnumerable<T> enumerable, bool continueOnCapturedContext, CancellationToken cancellationToken) { _enumerable = enumerable; _continueOnCapturedContext = continueOnCapturedContext; _cancellationToken = cancellationToken; } public ConfiguredCancelableAsyncEnumerable<T> ConfigureAwait(bool continueOnCapturedContext) { return new ConfiguredCancelableAsyncEnumerable<T>(_enumerable, continueOnCapturedContext, _cancellationToken); } public ConfiguredCancelableAsyncEnumerable<T> WithCancellation(CancellationToken cancellationToken) { return new ConfiguredCancelableAsyncEnumerable<T>(_enumerable, _continueOnCapturedContext, cancellationToken); } public Enumerator GetAsyncEnumerator() { return new Enumerator(_enumerable.GetAsyncEnumerator(_cancellationToken), _continueOnCapturedContext); } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] public sealed class EnumeratorCancellationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } } namespace System.Threading.Tasks { public static class TaskAsyncEnumerableExtensions { public static ConfiguredAsyncDisposable ConfigureAwait(this IAsyncDisposable source, bool continueOnCapturedContext) { return new ConfiguredAsyncDisposable(source, continueOnCapturedContext); } public static ConfiguredCancelableAsyncEnumerable<T> ConfigureAwait<T>(this IAsyncEnumerable<T> source, bool continueOnCapturedContext) { return new ConfiguredCancelableAsyncEnumerable<T>(source, continueOnCapturedContext, default(CancellationToken)); } public static ConfiguredCancelableAsyncEnumerable<T> WithCancellation<T>(this IAsyncEnumerable<T> source, CancellationToken cancellationToken) { return new ConfiguredCancelableAsyncEnumerable<T>(source, continueOnCapturedContext: true, cancellationToken); } } } namespace System.Threading.Tasks.Sources { [StructLayout(LayoutKind.Auto)] public struct ManualResetValueTaskSourceCore<TResult> { private Action<object> _continuation; private object _continuationState; private ExecutionContext _executionContext; private object _capturedContext; private bool _completed; private TResult _result; private ExceptionDispatchInfo _error; private short _version; public bool RunContinuationsAsynchronously { get; set; } public short Version => _version; public void Reset() { _version++; _completed = false; _result = default(TResult); _error = null; _executionContext = null; _capturedContext = null; _continuation = null; _continuationState = null; } public void SetResult(TResult result) { _result = result; SignalCompletion(); } public void SetException(Exception error) { _error = ExceptionDispatchInfo.Capture(error); SignalCompletion(); } public ValueTaskSourceStatus GetStatus(short token) { ValidateToken(token); if (_continuation != null && _completed) { if (_error != null) { if (!(_error.SourceException is OperationCanceledException)) { return ValueTaskSourceStatus.Faulted; } return ValueTaskSourceStatus.Canceled; } return ValueTaskSourceStatus.Succeeded; } return ValueTaskSourceStatus.Pending; } public TResult GetResult(short token) { ValidateToken(token); if (!_completed) { throw new InvalidOperationException(); } _error?.Throw(); return _result; } public void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) { ExceptionPolyfills.ThrowIfNull(continuation, "continuation"); ValidateToken(token); if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0) { _executionContext = ExecutionContext.Capture(); } if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) { SynchronizationContext current = SynchronizationContext.Current; if (current != null && current.GetType() != typeof(SynchronizationContext)) { _capturedContext = current; } else { TaskScheduler current2 = TaskScheduler.Current; if (current2 != TaskScheduler.Default) { _capturedContext = current2; } } } object obj = _continuation; if (obj == null) { _continuationState = state; obj = Interlocked.CompareExchange(ref _continuation, continuation, null); } if (obj == null) { return; } if (obj != System.Threading.Tasks.Sources.ManualResetValueTaskSourceCoreShared.s_sentinel) { throw new InvalidOperationException(); } object capturedContext = _capturedContext; if (capturedContext != null) { if (!(capturedContext is SynchronizationContext synchronizationContext)) { if (capturedContext is TaskScheduler scheduler) { Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, scheduler); } } else { synchronizationContext.Post(delegate(object s) { Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s; tuple.Item1(tuple.Item2); }, Tuple.Create(continuation, state)); } } else { Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } } private void ValidateToken(short token) { if (token != _version) { throw new InvalidOperationException(); } } private void SignalCompletion() { if (_completed) { throw new InvalidOperationException(); } _completed = true; if (_continuation == null && Interlocked.CompareExchange(ref _continuation, System.Threading.Tasks.Sources.ManualResetValueTaskSourceCoreShared.s_sentinel, null) == null) { return; } if (_executionContext != null) { ExecutionContext.Run(_executionContext, delegate(object s) { ((ManualResetValueTaskSourceCore<TResult>)s).InvokeContinuation(); }, this); } else { InvokeContinuation(); } } private void InvokeContinuation() { object capturedContext = _capturedContext; if (capturedContext != null) { if (!(capturedContext is SynchronizationContext synchronizationContext)) { if (capturedContext is TaskScheduler scheduler) { Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, scheduler); } } else { synchronizationContext.Post(delegate(object s) { Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s; tuple.Item1(tuple.Item2); }, Tuple.Create(_continuation, _continuationState)); } } else if (RunContinuationsAsynchronously) { Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } else { _continuation(_continuationState); } } } internal static class ManualResetValueTaskSourceCoreShared { internal static readonly Action<object> s_sentinel = CompletionSentinel; private static void CompletionSentinel(object _) { throw new InvalidOperationException(); } } }
SoundCloudExplode.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Sources; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using SoundCloudExplode.Bridge; using SoundCloudExplode.Common; using SoundCloudExplode.Exceptions; using SoundCloudExplode.Playlists; using SoundCloudExplode.Search; using SoundCloudExplode.Tracks; using SoundCloudExplode.Users; using SoundCloudExplode.Utils; using SoundCloudExplode.Utils.Extensions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Jerro")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("Copyright (C) Jerry Berry")] [assembly: AssemblyDescription("Library that provides an interface to query metadata of SoundCloud tracks and playlists, as well as to resolve and download audio.")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0-dev+034b0495b31081f77ec3dfd71aaa3668ea48e5bf")] [assembly: AssemblyProduct("SoundCloudExplode")] [assembly: AssemblyTitle("SoundCloudExplode")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/modestimpala/SoundCloudExplode")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } [ExcludeFromCodeCoverage] internal static class PolyfillExtensions { public static async Task<Stream> GetStreamAsync(this HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { try { HttpResponseMessage response = await httpClient.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); return await ReadAsStreamAsync(response.Content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (OperationCanceledException ex) when (ex.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); } } public static async Task<Stream> GetStreamAsync(this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { return await GetStreamAsync(httpClient, requestUri.ToString(), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<byte[]> GetByteArrayAsync(this HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { try { using HttpResponseMessage response = await httpClient.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); return await ReadAsByteArrayAsync(response.Content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (OperationCanceledException ex) when (ex.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); } } public static async Task<byte[]> GetByteArrayAsync(this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { return await GetByteArrayAsync(httpClient, requestUri.ToString(), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<string> GetStringAsync(this HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { try { using HttpResponseMessage response = await httpClient.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); return await ReadAsStringAsync(response.Content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (OperationCanceledException ex) when (ex.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); } } public static async Task<string> GetStringAsync(this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { return await GetStringAsync(httpClient, requestUri.ToString(), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<Stream> ReadAsStreamAsync(this HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await httpContent.ReadAsStreamAsync().ConfigureAwait(continueOnCapturedContext: false); } public static async Task<byte[]> ReadAsByteArrayAsync(this HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await httpContent.ReadAsByteArrayAsync().ConfigureAwait(continueOnCapturedContext: false); } public static async Task<string> ReadAsStringAsync(this HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await httpContent.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false); } public static async Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default(CancellationToken)) { TaskCompletionSource<object?> tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); try { process.EnableRaisingEvents = true; } catch when (process.HasExited) { return; } process.Exited += HandleExited; try { using (cancellationToken.Register(delegate { tcs.TrySetCanceled(cancellationToken); })) { await tcs.Task; } } finally { process.Exited -= HandleExited; } void HandleExited(object? sender, EventArgs args) { tcs.TrySetResult(null); } } public static bool IsAssignableTo(this Type type, Type? otherType) { return otherType?.IsAssignableFrom(type) ?? false; } public static string ReplaceLineEndings(this string str, string replacementText) { return Replace(Replace(Replace(str, "\r\n", "\n", StringComparison.Ordinal), "\r", "\n", StringComparison.Ordinal), "\n", replacementText, StringComparison.Ordinal); } public static string ReplaceLineEndings(this string str) { return ReplaceLineEndings(str, Environment.NewLine); } public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) { Task cancellationTask = Task.Delay(timeout, cancellationToken); Task finishedTask = await Task.WhenAny(new Task[2] { task, cancellationTask }).ConfigureAwait(continueOnCapturedContext: false); await finishedTask.ConfigureAwait(continueOnCapturedContext: false); if (finishedTask == cancellationTask) { throw new TimeoutException("The operation has timed out."); } } public static async Task WaitAsync(this Task task, CancellationToken cancellationToken) { await WaitAsync(task, Timeout.InfiniteTimeSpan, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task WaitAsync(this Task task, TimeSpan timeout) { await WaitAsync(task, timeout, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout, CancellationToken cancellationToken) { Task cancellationTask = Task.Delay(timeout, cancellationToken); Task finishedTask = await Task.WhenAny(new Task[2] { task, cancellationTask }).ConfigureAwait(continueOnCapturedContext: false); await finishedTask.ConfigureAwait(continueOnCapturedContext: false); if (finishedTask == cancellationTask) { throw new TimeoutException("The operation has timed out."); } return task.Result; } public static async Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken) { return await WaitAsync(task, Timeout.InfiniteTimeSpan, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout) { return await WaitAsync(task, timeout, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } public static int ReadAtLeast(this Stream stream, byte[] buffer, int minimumBytes, bool throwOnEndOfStream = true) { int i; int num; for (i = 0; i < buffer.Length; i += num) { num = stream.Read(buffer, i, Math.Min(minimumBytes, buffer.Length - i)); if (num <= 0) { break; } } if (i < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return i; } public static void ReadExactly(this Stream stream, byte[] buffer, int offset, int count) { int num; for (int i = 0; i < count; i += num) { num = stream.Read(buffer, offset + i, count - i); if (num <= 0) { throw new EndOfStreamException(); } } } public static void ReadExactly(this Stream stream, byte[] buffer) { stream.ReadExactly(buffer, 0, buffer.Length); } public static async Task<int> ReadAtLeastAsync(this Stream stream, byte[] buffer, int minimumBytes, bool throwOnEndOfStream = true, CancellationToken cancellationToken = default(CancellationToken)) { int totalBytesRead; int bytesRead; for (totalBytesRead = 0; totalBytesRead < buffer.Length; totalBytesRead += bytesRead) { bytesRead = await stream.ReadAsync(buffer, totalBytesRead, Math.Min(minimumBytes, buffer.Length - totalBytesRead), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (bytesRead <= 0) { break; } } if (totalBytesRead < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return totalBytesRead; } public static async Task ReadExactlyAsync(this Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken = default(CancellationToken)) { int bytesRead; for (int totalBytesRead = 0; totalBytesRead < count; totalBytesRead += bytesRead) { bytesRead = await stream.ReadAsync(buffer, offset + totalBytesRead, count - totalBytesRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (bytesRead <= 0) { throw new EndOfStreamException(); } } } public static async Task ReadExactlyAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { await stream.ReadExactlyAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static int ReadAtLeast(this Stream stream, Span<byte> buffer, int minimumBytes, bool throwOnEndOfStream = true) { int i; int num; for (i = 0; i < buffer.Length; i += num) { num = Read(stream, buffer.Slice(i)); if (num <= 0) { break; } } if (i < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return i; } public static void ReadExactly(this Stream stream, Span<byte> buffer) { byte[] array = buffer.ToArray(); stream.ReadExactly(array, 0, array.Length); array.CopyTo(buffer); } public static async Task<int> ReadAtLeastAsync(this Stream stream, Memory<byte> buffer, int minimumBytes, bool throwOnEndOfStream = true, CancellationToken cancellationToken = default(CancellationToken)) { int totalBytesRead; int bytesRead; for (totalBytesRead = 0; totalBytesRead < buffer.Length; totalBytesRead += bytesRead) { bytesRead = await ReadAsync(stream, buffer.Slice(totalBytesRead), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (bytesRead <= 0) { break; } } if (totalBytesRead < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return totalBytesRead; } public static async Task ReadExactlyAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken)) { byte[] bufferArray = buffer.ToArray(); await stream.ReadExactlyAsync(bufferArray, 0, bufferArray.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); bufferArray.CopyTo(buffer); } public static Task CancelAsync(this CancellationTokenSource cts) { cts.Cancel(); return Task.CompletedTask; } public static void Deconstruct(this DictionaryEntry entry, out object key, out object? value) { key = entry.Key; value = entry.Value; } public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value) { key = pair.Key; value = pair.Value; } public static IEnumerable<Match> AsEnumerable(this MatchCollection matchCollection) { return matchCollection.Cast<Match>(); } public static IEnumerator<Match> GetEnumerator(this MatchCollection matchCollection) { return matchCollection.AsEnumerable().GetEnumerator(); } public static Match[] ToArray(this MatchCollection matchCollection) { return matchCollection.AsEnumerable().ToArray(); } public static bool StartsWith(this string str, char c) { return str.Length > 0 && str[0] == c; } public static bool EndsWith(this string str, char c) { int result; if (str.Length > 0) { result = ((str[str.Length - 1] == c) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } public static bool Contains(this string str, char c) { return str.IndexOf(c) >= 0; } public static string Replace(this string str, string oldValue, string? newValue, StringComparison comparison) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; int num2 = 0; while (true) { num = str.IndexOf(oldValue, num, comparison); if (num < 0) { break; } stringBuilder.Append(str, num2, num - num2); stringBuilder.Append(newValue); num += oldValue.Length; num2 = num; } stringBuilder.Append(str, num2, str.Length - num2); return stringBuilder.ToString(); } public static string Replace(this string str, string oldValue, string? newValue, bool ignoreCase, CultureInfo? culture) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; int num2 = 0; while (true) { num = (culture ?? CultureInfo.CurrentCulture).CompareInfo.IndexOf(str, oldValue, num, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); if (num < 0) { break; } stringBuilder.Append(str, num2, num - num2); stringBuilder.Append(newValue); num += oldValue.Length; num2 = num; } stringBuilder.Append(str, num2, str.Length - num2); return stringBuilder.ToString(); } public static string[] Split(this string str, char separator, int count, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new char[1] { separator }, count, options); } public static string[] Split(this string str, char separator, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new char[1] { separator }, options); } public static string[] Split(this string str, string? separator, int count, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new string[1] { separator ?? "" }, count, options); } public static string[] Split(this string str, string? separator, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new string[1] { separator ?? "" }, options); } public static void NextBytes(this Random random, Span<byte> buffer) { byte[] array = buffer.ToArray(); random.NextBytes(array); array.CopyTo(buffer); } public static int Read(this Stream stream, byte[] buffer) { return stream.Read(buffer, 0, buffer.Length); } public static void Write(this Stream stream, byte[] buffer) { stream.Write(buffer, 0, buffer.Length); } public static async Task CopyToAsync(this Stream stream, Stream destination, CancellationToken cancellationToken = default(CancellationToken)) { await stream.CopyToAsync(destination, 81920, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<int> ReadAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { return await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task WriteAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static int Read(this Stream stream, Span<byte> buffer) { byte[] array = buffer.ToArray(); int result = stream.Read(array, 0, array.Length); array.CopyTo(buffer); return result; } public static void Write(this Stream stream, ReadOnlySpan<byte> buffer) { byte[] array = buffer.ToArray(); stream.Write(array, 0, array.Length); } public static async Task<int> ReadAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken)) { byte[] bufferArray = buffer.ToArray(); int result = await stream.ReadAsync(bufferArray, 0, bufferArray.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); bufferArray.CopyTo(buffer); return result; } public static async Task WriteAsync(this Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken)) { byte[] bufferArray = buffer.ToArray(); await stream.WriteAsync(bufferArray, 0, bufferArray.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static int Read(this StreamReader reader, char[] buffer) { return reader.Read(buffer, 0, buffer.Length); } public static async Task<int> ReadAsync(this StreamReader reader, char[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await reader.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(continueOnCapturedContext: false); } public static int Read(this StreamReader reader, Span<char> buffer) { char[] array = buffer.ToArray(); int result = reader.Read(array, 0, array.Length); array.CopyTo(buffer); return result; } public static async Task<int> ReadAsync(this StreamReader reader, Memory<char> buffer, CancellationToken cancellationToken = default(CancellationToken)) { char[] bufferArray = buffer.ToArray(); cancellationToken.ThrowIfCancellationRequested(); int result = await reader.ReadAsync(bufferArray, 0, bufferArray.Length).ConfigureAwait(continueOnCapturedContext: false); bufferArray.CopyTo(buffer); return result; } public static void Write(this StreamWriter writer, ReadOnlySpan<char> buffer) { char[] array = buffer.ToArray(); writer.Write(array, 0, array.Length); } public static async Task WriteAsync(this StreamWriter writer, Memory<char> buffer, CancellationToken cancellationToken = default(CancellationToken)) { char[] bufferArray = buffer.ToArray(); cancellationToken.ThrowIfCancellationRequested(); await writer.WriteAsync(bufferArray, 0, bufferArray.Length).ConfigureAwait(continueOnCapturedContext: false); } public static bool Contains(this string str, char c, StringComparison comparison) { return Contains(str, c.ToString(), comparison); } public static bool Contains(this string str, string sub, StringComparison comparison) { return str.IndexOf(sub, comparison) >= 0; } } namespace SoundCloudExplode { public static class Constants { public const string ClientId = "wDSKS1Bp8WmdlRPkZ7NQXGs67PMXl2Nd"; public const string ResolveEndpoint = "https://api-v2.soundcloud.com/resolve"; public const string TrackEndpoint = "https://api-v2.soundcloud.com/tracks"; public const int DefaultOffset = 0; public const int DefaultLimit = 50; public const int MinLimit = 0; public const int MaxLimit = 200; } public interface ISoundCloudClient { bool IsInitialized { get; } ISearchClient Search { get; } ITrackClient Tracks { get; } IPlaylistClient Playlists { get; } IUserClient Users { get; } Task InitializeAsync(CancellationToken cancellationToken = default(CancellationToken)); Task<string> GetClientIdAsync(CancellationToken cancellationToken = default(CancellationToken)); Task<Kind> GetUrlKindAsync(string url, CancellationToken cancellationToken = default(CancellationToken)); ValueTask DownloadAsync(Track track, string filePath, IProgress<double>? progress = null, Dictionary<string, string>? headers = null, CancellationToken cancellationToken = default(CancellationToken)); } public class SoundCloudClient : ISoundCloudClient { private readonly HttpClient _http; private readonly SoundcloudEndpoint _endpoint; private readonly string BaseUrl = "https://soundcloud.com"; public string ClientId { get; set; } public bool IsInitialized { get; private set; } public ISearchClient Search { get; } public ITrackClient Tracks { get; } public IPlaylistClient Playlists { get; } public IUserClient Users { get; } public SoundCloudClient(string clientId, HttpClient http, string? authorization = null) { ClientId = clientId; _http = http; if (!string.IsNullOrWhiteSpace(authorization)) { http.DefaultRequestHeaders.Add("Authorization", authorization); } _endpoint = new SoundcloudEndpoint(http) { ClientId = clientId }; Search = new SearchClient(http, _endpoint); Tracks = new TrackClient(http, _endpoint); Playlists = new PlaylistClient(http, _endpoint); Users = new UserClient(http, _endpoint); } public SoundCloudClient(string clientId, HttpClient http) : this(clientId, http, null) { } public SoundCloudClient() : this("wDSKS1Bp8WmdlRPkZ7NQXGs67PMXl2Nd", Http.Client) { } public SoundCloudClient(HttpClient http) : this("wDSKS1Bp8WmdlRPkZ7NQXGs67PMXl2Nd", http) { } public SoundCloudClient(string clientId, string authorization) : this(clientId, Http.Client, authorization) { } public SoundCloudClient(string clientId) : this(clientId, Http.Client) { } public async Task InitializeAsync(CancellationToken cancellationToken = default(CancellationToken)) { ClientId = await GetClientIdAsync(cancellationToken); _endpoint.ClientId = ClientId; IsInitialized = true; } public async Task<string> GetClientIdAsync(CancellationToken cancellationToken = default(CancellationToken)) { MatchCollection scripts = Regex.Matches(await _http.ExecuteGetAsync(BaseUrl, cancellationToken), "<script.*?src=\"(.*?)\""); string scriptUrl = scripts.Cast<Match>().LastOrDefault()?.Groups[1].Value; if (string.IsNullOrEmpty(scriptUrl)) { return string.Empty; } return (await _http.ExecuteGetAsync(scriptUrl, cancellationToken)).Split(new string[1] { ",client_id" }, StringSplitOptions.None)[1].Split(new char[1] { '"' })[1]; } public async Task<Kind> GetUrlKindAsync(string url, CancellationToken cancellationToken = default(CancellationToken)) { string resolvedJson = await _endpoint.ResolveUrlAsync(url, cancellationToken); if (string.IsNullOrWhiteSpace(resolvedJson)) { throw new SoundcloudExplodeException("Failed to resolve url."); } JObject jObject = JObject.Parse(resolvedJson); return JsonConvert.DeserializeObject<Kind>(((object)jObject["kind"]).ToString(), JsonSettings.Default); } public async ValueTask DownloadAsync(Track track, string filePath, IProgress<double>? progress = null, Dictionary<string, string>? headers = null, CancellationToken cancellationToken = default(CancellationToken)) { string mp3TrackMediaUrl = await Tracks.GetDownloadUrlAsync(track, cancellationToken); if (mp3TrackMediaUrl == null) { return; } string dir = Path.GetDirectoryName(filePath); if (dir == null) { return; } if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } using FileStream destination = File.Create(filePath); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, mp3TrackMediaUrl); if (headers != null) { foreach (var (key, value) in headers) { request.Headers.TryAddWithoutValidation(key, value); } } HttpResponseMessage response = await _http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"Response status code does not indicate success: {(int)response.StatusCode} ({response.StatusCode})." + Environment.NewLine + "Request:" + Environment.NewLine + request); } await StreamExtensions.CopyToAsync(totalLength: response.Content.Headers.ContentLength.GetValueOrDefault(), source: await PolyfillExtensions.ReadAsStreamAsync(response.Content, cancellationToken), destination: destination, progress: progress, bufferSize: 4096, cancellationToken: cancellationToken); } } internal static class JsonSettings { public static readonly JsonSerializerSettings Default = new JsonSerializerSettings { Converters = { (JsonConverter)new StringEnumConverter() }, NullValueHandling = (NullValueHandling)1 }; } } namespace SoundCloudExplode.Utils { internal static class Http { private static readonly Lazy<HttpClient> HttpClientLazy = new Lazy<HttpClient>(delegate { HttpClientHandler handler = new HttpClientHandler(); return new HttpClient(handler, disposeHandler: true); }); public static HttpClient Client => HttpClientLazy.Value; public static string ChromeUserAgent() { int num = Randomizer.Instance.Next(62, 70); int num2 = Randomizer.Instance.Next(2100, 3538); int num3 = Randomizer.Instance.Next(170); return "Mozilla/5.0 (" + RandomWindowsVersion() + ") AppleWebKit/537.36 (KHTML, like Gecko) " + $"Chrome/{num}.0.{num2}.{num3} Safari/537.36"; } private static string RandomWindowsVersion() { string text = "Windows NT "; int num = Randomizer.Instance.Next(99) + 1; text = ((num >= 1 && num <= 45) ? (text + "10.0") : ((num > 45 && num <= 80) ? (text + "6.1") : ((num <= 80 || num > 95) ? (text + "6.2") : (text + "6.3")))); if (Randomizer.Instance.NextDouble() <= 0.65) { text += ((Randomizer.Instance.NextDouble() <= 0.5) ? "; WOW64" : "; Win64; x64"); } return text; } } public static class Randomizer { [ThreadStatic] private static Random _rand; public static Random Instance => _rand ?? (_rand = Generate()); private static Random Generate() { byte[] array = new byte[4]; using RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create(); randomNumberGenerator.GetBytes(array); return new Random(BitConverter.ToInt32(array, 0)); } } } namespace SoundCloudExplode.Utils.Extensions { internal static class AsyncCollectionExtensions { public static async IAsyncEnumerable<T> TakeAsync<T>(this IAsyncEnumerable<T> source, int count) { int currentCount = 0; await foreach (T i in source) { if (currentCount >= count) { break; } yield return i; currentCount++; } } public static async IAsyncEnumerable<T> SelectManyAsync<TSource, T>(this IAsyncEnumerable<TSource> source, Func<TSource, IEnumerable<T>> transform) { await foreach (TSource i in source) { foreach (T item in transform(i)) { yield return item; } } } public static async IAsyncEnumerable<T> OfTypeAsync<T>(this IAsyncEnumerable<object> source) { T match = default(T); await foreach (object i in source) { int num; if (i is T) { match = (T)i; num = 1; } else { num = 0; } if (num != 0) { yield return match; } match = default(T); } } public static async ValueTask<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> source) { List<T> list = new List<T>(); await foreach (T i in source) { list.Add(i); } return list; } } public static class EnumerableExtensions { public static IEnumerable<IEnumerable<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize) { return from x in source.Select((T x, int i) => new { Index = i, Value = x }) group x by x.Index / chunkSize into x select from v in x select v.Value; } } internal static class GenericExtensions { public static TOut Pipe<TIn, TOut>(this TIn input, Func<TIn, TOut> transform) { return transform(input); } public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken, Action action, bool useSynchronizationContext = true) { using (cancellationToken.Register(action, useSynchronizationContext)) { try { return await task; } catch (Exception ex2) { Exception ex = ex2; if (cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex, cancellationToken); } throw; } } } } internal static class HttpExtensions { public static async ValueTask<string> ExecuteGetAsync(this HttpClient http, string url, CancellationToken cancellationToken = default(CancellationToken)) { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url); return await http.ExecuteAsync(request, cancellationToken); } public static async ValueTask<string> ExecuteAsync(this HttpClient http, HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) { if (!request.Headers.Contains("User-Agent")) { request.Headers.Add("User-Agent", Http.ChromeUserAgent()); } using HttpResponseMessage response = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); if (response.StatusCode == HttpStatusCode.TooManyRequests) { throw new RequestLimitExceededException("Exceeded request rate limit. Please try again later. "); } if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"Response status code does not indicate success: {(int)response.StatusCode} ({response.StatusCode})." + Environment.NewLine + "Request:" + Environment.NewLine + request); } return await PolyfillExtensions.ReadAsStringAsync(response.Content, cancellationToken); } } internal static class StreamExtensions { public static async ValueTask CopyToAsync(this Stream source, Stream destination, long totalLength, IProgress<double>? progress = null, int bufferSize = 4096, CancellationToken cancellationToken = default(CancellationToken)) { using IMemoryOwner<byte> buffer = MemoryPool<byte>.Shared.Rent(bufferSize); long totalBytesRead = 0L; while (true) { int bytesRead = await PolyfillExtensions.ReadAsync(source, buffer.Memory, cancellationToken); if (bytesRead <= 0) { break; } await PolyfillExtensions.WriteAsync(destination, buffer.Memory.Slice(0, bytesRead), cancellationToken); totalBytesRead += bytesRead; progress?.Report(1.0 * (double)totalBytesRead / (double)totalLength); } } } } namespace SoundCloudExplode.Users { public class Badges { [JsonProperty("pro_unlimited")] public bool ProUnlimited { get; set; } [JsonProperty("verified")] public bool Verified { get; set; } } public interface IUserClient { bool IsUrlValid(string url); bool IsLikesUrlValid(string url); ValueTask<User> GetAsync(string url, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Batch<Track>> GetTrackBatchesAsync(string url, UserTrackSortBy trackQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Track> GetTracksAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Track> GetTracksAsync(string url, CancellationToken cancellationToken); IAsyncEnumerable<Track> GetPopularTracksAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Track> GetPopularTracksAsync(string url, CancellationToken cancellationToken); IAsyncEnumerable<Track> GetLikedTracksAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Track> GetLikedTracksAsync(string url, CancellationToken cancellationToken); IAsyncEnumerable<Batch<Playlist>> GetPlaylistBatchesAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Playlist> GetPlaylistsAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Playlist> GetPlaylistsAsync(string url, CancellationToken cancellationToken); IAsyncEnumerable<Batch<Playlist>> GetAlbumBatchesAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Playlist> GetAlbumsAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Playlist> GetAlbumsAsync(string url, CancellationToken cancellationToken); } public class PlaylistUser { [JsonProperty("avatar_url")] public Uri? AvatarUrl { get; set; } [JsonProperty("city")] public object? City { get; set; } [JsonProperty("comments_count")] public long CommentsCount { get; set; } [JsonProperty("country_code")] public string? CountryCode { get; set; } [JsonProperty("created_at")] public DateTimeOffset? CreatedAt { get; set; } [JsonProperty("creator_subscriptions")] public List<CreatorSubscription> CreatorSubscriptions { get; set; } = new List<CreatorSubscription>(); [JsonProperty("creator_subscription")] public CreatorSubscription? CreatorSubscription { get; set; } [JsonProperty("description")] public object? Description { get; set; } [JsonProperty("followers_count")] public long? FollowersCount { get; set; } [JsonProperty("followings_count")] public long? FollowingsCount { get; set; } [JsonProperty("first_name")] public string? FirstName { get; set; } [JsonProperty("full_name")] public string? FullName { get; set; } [JsonProperty("groups_count")] public long? GroupsCount { get; set; } [JsonProperty("id")] public long? Id { get; set; } [JsonProperty("kind")] public string? Kind { get; set; } [JsonProperty("last_modified")] public DateTimeOffset? LastModified { get; set; } [JsonProperty("last_name")] public string? LastName { get; set; } [JsonProperty("likes_count")] public long? LikesCount { get; set; } [JsonProperty("playlist_likes_count")] public long? PlaylistLikesCount { get; set; } [JsonProperty("permalink")] public string? Permalink { get; set; } [JsonProperty("permalink_url")] public Uri? PermalinkUrl { get; set; } [JsonProperty("playlist_count")] public long? PlaylistCount { get; set; } [JsonProperty("reposts_count")] public object? RepostsCount { get; set; } [JsonProperty("track_count")] public long? TrackCount { get; set; } [JsonProperty("uri")] public Uri? Uri { get; set; } [JsonProperty("urn")] public string? Urn { get; set; } [JsonProperty("username")] public string? Username { get; set; } [JsonProperty("verified")] public bool Verified { get; set; } [JsonProperty("visuals")] public Visuals? Visuals { get; set; } [JsonProperty("badges")] public Badges? Badges { get; set; } } public class User : IBatchItem { [JsonProperty("avatar_url")] public Uri? AvatarUrl { get; set; } [JsonProperty("first_name")] public string? FirstName { get; set; } [JsonProperty("full_name")] public string? FullName { get; set; } [JsonProperty("id")] public long? Id { get; set; } [JsonProperty("kind")] public Kind Kind { get; set; } [JsonProperty("last_modified")] public DateTimeOffset? LastModified { get; set; } [JsonProperty("last_name")] public string? LastName { get; set; } [JsonProperty("permalink")] public string? Permalink { get; set; } [JsonProperty("permalink_url")] public string? PermalinkUrl { get; set; } [JsonProperty("uri")] public Uri? Uri { get; set; } [JsonProperty("urn")] public string? Urn { get; set; } [JsonProperty("username")] public string? Username { get; set; } [JsonProperty("verified")] public bool Verified { get; set; } [JsonProperty("city")] public string? City { get; set; } [JsonProperty("country_code")] public string? CountryCode { get; set; } [JsonProperty("badges")] public Badges? Badges { get; set; } [ExcludeFromCodeCoverage] public override string ToString() { return "User (" + ((!string.IsNullOrWhiteSpace(FullName)) ? FullName : Username) + ")"; } } public class UserClient : IUserClient { [CompilerGenerated] private sealed class <GetAlbumBatchesAsync>d__17 : IAsyncEnumerable<Batch<Playlist>>, IAsyncEnumerator<Batch<Playlist>>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private Batch<Playlist> <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; private string url; public string <>3__url; private int offset; public int <>3__offset; private int limit; public int <>3__limit; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; public UserClient <>4__this; private User <user>5__1; private string <nextUrl>5__2; private User <>s__3; private string <response>5__4; private JObject <doc>5__5; private JToken <collection>5__6; private List<Playlist> <list>5__7; private string <>s__8; private ValueTaskAwaiter<User> <>u__1; private ValueTaskAwaiter<string> <>u__2; Batch<Playlist> IAsyncEnumerator<Batch<Playlist>>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAlbumBatchesAsync>d__17(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; try { ValueTaskAwaiter<User> awaiter2; ValueTaskAwaiter<string> awaiter; switch (num) { default: if (!<>w__disposeMode) { num = (<>1__state = -1); Limitor.Validate(limit); <>2__current = null; awaiter2 = <>4__this.GetAsync(url, cancellationToken).GetAwaiter(); if (!awaiter2.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter2; <GetAlbumBatchesAsync>d__17 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine); return; } goto IL_00ce; } goto end_IL_0007; case 0: awaiter2 = <>u__1; <>u__1 = default(ValueTaskAwaiter<User>); num = (<>1__state = -1); goto IL_00ce; case 1: awaiter = <>u__2; <>u__2 = default(ValueTaskAwaiter<string>); num = (<>1__state = -1); break; case -4: { num = (<>1__state = -1); if (!<>w__disposeMode) { <nextUrl>5__2 = ((object)<doc>5__5["next_href"])?.ToString(); if (!string.IsNullOrEmpty(<nextUrl>5__2)) { <nextUrl>5__2 = <nextUrl>5__2 + "&client_id=" + <>4__this.<endpoint>P.ClientId; <response>5__4 = null; <doc>5__5 = null; <collection>5__6 = null; <list>5__7 = null; goto IL_034d; } } goto end_IL_0007; } IL_00ce: <>s__3 = awaiter2.GetResult(); <user>5__1 = <>s__3; <>s__3 = null; if (<user>5__1 != null) { <nextUrl>5__2 = null; goto IL_034d; } <>w__disposeMode = true; goto end_IL_0007; IL_034d: url = <nextUrl>5__2 ?? $"https://api-v2.soundcloud.com/users/{<user>5__1.Id}/albums?offset={offset}&limit={limit}&client_id={<>4__this.<endpoint>P.ClientId}"; <>2__current = null; awaiter = <>4__this.<http>P.ExecuteGetAsync(url, cancellationToken).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__2 = awaiter; <GetAlbumBatchesAsync>d__17 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } break; } <>s__8 = awaiter.GetResult(); <response>5__4 = <>s__8; <>s__8 = null; <doc>5__5 = JObject.Parse(<response>5__4); <collection>5__6 = <doc>5__5["collection"]; if (<collection>5__6 != null && ((IEnumerable<JToken>)<collection>5__6).Any()) { <list>5__7 = JsonConvert.DeserializeObject<List<Playlist>>(((object)<collection>5__6).ToString(), JsonSettings.Default); if (<list>5__7 != null && <list>5__7.Count != 0) { <>2__current = Batch.Create(<list>5__7); num = (<>1__state = -4); goto IL_0459; } } end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <user>5__1 = null; <nextUrl>5__2 = null; <>s__3 = null; <response>5__4 = null; <doc>5__5 = null; <collection>5__6 = null; <list>5__7 = null; <>s__8 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <user>5__1 = null; <nextUrl>5__2 = null; <>s__3 = null; <response>5__4 = null; <doc>5__5 = null; <collection>5__6 = null; <list>5__7 = null; <>s__8 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_0459: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<Batch<Playlist>> IAsyncEnumerable<Batch<Playlist>>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetAlbumBatchesAsync>d__17 <GetAlbumBatchesAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetAlbumBatchesAsync>d__ = this; } else { <GetAlbumBatchesAsync>d__ = new <GetAlbumBatchesAsync>d__17(-3) { <>4__this = <>4__this }; } <GetAlbumBatchesAsync>d__.url = <>3__url; <GetAlbumBatchesAsync>d__.offset = <>3__offset; <GetAlbumBatchesAsync>d__.limit = <>3__limit; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetAlbumBatchesAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetAlbumBatchesAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetAlbumBatchesAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetAlbumBatchesAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<Batch<Playlist>>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetAlbumBatchesAsync>d__17 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetAlbumBatchesAsync>d__17 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } [CompilerGenerated] private sealed class <GetPlaylistBatchesAsync>d__14 : IAsyncEnumerable<Batch<Playlist>>, IAsyncEnumerator<Batch<Playlist>>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private Batch<Playlist> <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; private string url; public string <>3__url; private int offset; public int <>3__offset; private int limit; public int <>3__limit; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; public UserClient <>4__this; private User <user>5__1; private string <nextUrl>5__2; private User <>s__3; private string <response>5__4; private JObject <doc>5__5; private JToken <collection>5__6; private List<Playlist> <list>5__7; private string <>s__8; private ValueTaskAwaiter<User> <>u__1; private ValueTaskAwaiter<string> <>u__2; Batch<Playlist> IAsyncEnumerator<Batch<Playlist>>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetPlaylistBatchesAsync>d__14(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; try { ValueTaskAwaiter<User> awaiter2; ValueTaskAwaiter<string> awaiter; switch (num) { default: if (!<>w__disposeMode) { num = (<>1__state = -1); Limitor.Validate(limit); <>2__current = null; awaiter2 = <>4__this.GetAsync(url, cancellationToken).GetAwaiter(); if (!awaiter2.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter2; <GetPlaylistBatchesAsync>d__14 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine); return; } goto IL_00ce; } goto end_IL_0007; case 0: awaiter2 = <>u__1; <>u__1 = default(ValueTaskAwaiter<User>); num = (<>1__state = -1); goto IL_00ce; case 1: awaiter = <>u__2; <>u__2 = default(ValueTaskAwaiter<string>); num = (<>1__state = -1); break; case -4: { num = (<>1__state = -1); if (!<>w__disposeMode) { <nextUrl>5__2 = ((object)<doc>5__5["next_href"])?.ToString(); if (!string.IsNullOrEmpty(<nextUrl>5__2)) { <nextUrl>5__2 = <nextUrl>5__2 + "&client_id=" + <>4__this.<endpoint>P.ClientId; <response>5__4 = null; <doc>5__5 = null; <collection>5__6 = null; <list>5__7 = null; goto IL_034d; } } goto end_IL_0007; } IL_00ce: <>s__3 = awaiter2.GetResult(); <user>5__1 = <>s__3; <>s__3 = null; if (<user>5__1 != null) { <nextUrl>5__2 = null; goto IL_034d; } <>w__disposeMode = true; goto end_IL_0007; IL_034d: url = <nextUrl>5__2 ?? $"https://api-v2.soundcloud.com/users/{<user>5__1.Id}/playlists?offset={offset}&limit={limit}&client_id={<>4__this.<endpoint>P.ClientId}"; <>2__current = null; awaiter = <>4__this.<http>P.ExecuteGetAsync(url, cancellationToken).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__2 = awaiter; <GetPlaylistBatchesAsync>d__14 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } break; } <>s__8 = awaiter.GetResult(); <response>5__4 = <>s__8; <>s__8 = null; <doc>5__5 = JObject.Parse(<response>5__4); <collection>5__6 = <doc>5__5["collection"]; if (<collection>5__6 != null && ((IEnumerable<JToken>)<collection>5__6).Any()) { <list>5__7 = JsonConvert.DeserializeObject<List<Playlist>>(((object)<collection>5__6).ToString(), JsonSettings.Default); if (<list>5__7 != null && <list>5__7.Count != 0) { <>2__current = Batch.Create(<list>5__7); num = (<>1__state = -4); goto IL_0459; } } end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <user>5__1 = null; <nextUrl>5__2 = null; <>s__3 = null; <response>5__4 = null; <doc>5__5 = null; <collection>5__6 = null; <list>5__7 = null; <>s__8 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <user>5__1 = null; <nextUrl>5__2 = null; <>s__3 = null; <response>5__4 = null; <doc>5__5 = null; <collection>5__6 = null; <list>5__7 = null; <>s__8 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_0459: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<Batch<Playlist>> IAsyncEnumerable<Batch<Playlist>>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetPlaylistBatchesAsync>d__14 <GetPlaylistBatchesAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetPlaylistBatchesAsync>d__ = this; } else { <GetPlaylistBatchesAsync>d__ = new <GetPlaylistBatchesAsync>d__14(-3) { <>4__this = <>4__this }; } <GetPlaylistBatchesAsync>d__.url = <>3__url; <GetPlaylistBatchesAsync>d__.offset = <>3__offset; <GetPlaylistBatchesAsync>d__.limit = <>3__limit; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetPlaylistBatchesAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetPlaylistBatchesAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetPlaylistBatchesAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetPlaylistBatchesAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<Batch<Playlist>>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetPlaylistBatchesAsync>d__14 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetPlaylistBatchesAsync>d__14 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } [CompilerGenerated] private sealed class <GetTrackBatchesAsync>d__7 : IAsyncEnumerable<Batch<Track>>, IAsyncEnumerator<Batch<Track>>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private Batch<Track> <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; private string url; public string <>3__url; private UserTrackSortBy trackQuery; public UserTrackSortBy <>3__trackQuery; private int offset; public int <>3__offset; private int limit; public int <>3__limit; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; public UserClient <>4__this; private User <user>5__1; private string <queryPart>5__2; private string <nextUrl>5__3; private User <>s__4; private string <response>5__5; private JObject <doc>5__6; private JToken <collection>5__7; private string <>s__8; private List<Track> <list>5__9; private List<Track> <list>5__10; private ValueTaskAwaiter<User> <>u__1; private ValueTaskAwaiter<string> <>u__2; Batch<Track> IAsyncEnumerator<Batch<Track>>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetTrackBatchesAsync>d__7(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; try { ValueTaskAwaiter<User> awaiter2; ValueTaskAwaiter<string> awaiter; switch (num) { default: if (!<>w__disposeMode) { num = (<>1__state = -1); Limitor.Validate(limit); <>2__current = null; awaiter2 = <>4__this.GetAsync(url, cancellationToken).GetAwaiter(); if (!awaiter2.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter2; <GetTrackBatchesAsync>d__7 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine); return; } goto IL_00d7; } goto end_IL_0007; case 0: awaiter2 = <>u__1; <>u__1 = default(ValueTaskAwaiter<User>); num = (<>1__state = -1); goto IL_00d7; case 1: awaiter = <>u__2; <>u__2 = default(ValueTaskAwaiter<string>); num = (<>1__state = -1); break; case -4: num = (<>1__state = -1); if (!<>w__disposeMode) { <list>5__9 = null; goto IL_0401; } goto end_IL_0007; case -5: { num = (<>1__state = -1); if (!<>w__disposeMode) { <list>5__10 = null; goto IL_0401; } goto end_IL_0007; } IL_0472: url = <nextUrl>5__3 ?? $"https://api-v2.soundcloud.com/users/{<user>5__1.Id}/{<queryPart>5__2}?offset={offset}&limit={limit}&client_id={<>4__this.<endpoint>P.ClientId}"; <>2__current = null; awaiter = <>4__this.<http>P.ExecuteGetAsync(url, cancellationToken).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__2 = awaiter; <GetTrackBatchesAsync>d__7 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } break; IL_0401: <nextUrl>5__3 = ((object)<doc>5__6["next_href"])?.ToString(); if (!string.IsNullOrEmpty(<nextUrl>5__3)) { <nextUrl>5__3 = <nextUrl>5__3 + "&client_id=" + <>4__this.<endpoint>P.ClientId; <response>5__5 = null; <doc>5__6 = null; <collection>5__7 = null; goto IL_0472; } goto end_IL_0007; IL_00d7: <>s__4 = awaiter2.GetResult(); <user>5__1 = <>s__4; <>s__4 = null; if (<user>5__1 != null) { if (1 == 0) { } string text = trackQuery switch { UserTrackSortBy.Popular => "toptracks", UserTrackSortBy.Likes => "track_likes", _ => "tracks", }; if (1 == 0) { } <queryPart>5__2 = text; <nextUrl>5__3 = null; goto IL_0472; } <>w__disposeMode = true; goto end_IL_0007; } <>s__8 = awaiter.GetResult(); <response>5__5 = <>s__8; <>s__8 = null; <doc>5__6 = JObject.Parse(<response>5__5); <collection>5__7 = <doc>5__6["collection"]; if (<collection>5__7 != null && ((IEnumerable<JToken>)<collection>5__7).Any()) { if (trackQuery == UserTrackSortBy.Likes) { <list>5__9 = (from x in (IEnumerable<JToken>)<collection>5__7 select JsonConvert.DeserializeObject<Track>(((object)x[(object)"track"]).ToString(), JsonSettings.Default) into track where track != null select (track)).ToList(); <>2__current = Batch.Create(<list>5__9); num = (<>1__state = -4); goto IL_059a; } <list>5__10 = JsonConvert.DeserializeObject<List<Track>>(((object)<collection>5__7).ToString(), JsonSettings.Default); if (<list>5__10 != null && <list>5__10.Count != 0) { <>2__current = Batch.Create(<list>5__10); num = (<>1__state = -5); goto IL_059a; } } end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <user>5__1 = null; <queryPart>5__2 = null; <nextUrl>5__3 = null; <>s__4 = null; <response>5__5 = null; <doc>5__6 = null; <collection>5__7 = null; <>s__8 = null; <list>5__9 = null; <list>5__10 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <user>5__1 = null; <queryPart>5__2 = null; <nextUrl>5__3 = null; <>s__4 = null; <response>5__5 = null; <doc>5__6 = null; <collection>5__7 = null; <>s__8 = null; <list>5__9 = null; <list>5__10 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_059a: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<Batch<Track>> IAsyncEnumerable<Batch<Track>>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetTrackBatchesAsync>d__7 <GetTrackBatchesAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetTrackBatchesAsync>d__ = this; } else { <GetTrackBatchesAsync>d__ = new <GetTrackBatchesAsync>d__7(-3) { <>4__this = <>4__this }; } <GetTrackBatchesAsync>d__.url = <>3__url; <GetTrackBatchesAsync>d__.trackQuery = <>3__trackQuery; <GetTrackBatchesAsync>d__.offset = <>3__offset; <GetTrackBatchesAsync>d__.limit = <>3__limit; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetTrackBatchesAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetTrackBatchesAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetTrackBatchesAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetTrackBatchesAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<Batch<Track>>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetTrackBatchesAsync>d__7 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetTrackBatchesAsync>d__7 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpClient <http>P; [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private SoundcloudEndpoint <endpoint>P; private readonly Regex LikesRegex; public UserClient(HttpClient http, SoundcloudEndpoint endpoint) { <http>P = http; <endpoint>P = endpoint; LikesRegex = new Regex("soundcloud\\..+?\\/(.*?)\\/likes"); base..ctor(); } public bool IsUrlValid(string url) { if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { return false; } url = url.ToLower(); UriBuilder uriBuilder = new UriBuilder(url); return LikesRegex.IsMatch(url) || ((uriBuilder.Host == "soundcloud.com" || uriBuilder.Host == "m.soundcloud.com") && uriBuilder.Uri.Segments.Length == 2); } public bool IsLikesUrlValid(string url) { return Uri.IsWellFormedUriString(url, UriKind.Absolute) && LikesRegex.IsMatch(url); } public async ValueTask<User> GetAsync(string url, CancellationToken cancellationToken = default(CancellationToken)) { if (!IsUrlValid(url)) { throw new SoundcloudExplodeException("Invalid user url"); } return JsonConvert.DeserializeObject<User>(await <endpoint>P.ResolveUrlAsync(url, cancellationToken), JsonSettings.Default); } [AsyncIteratorStateMachine(typeof(<GetTrackBatchesAsync>d__7))] public IAsyncEnumerable<Batch<Track>> GetTrackBatchesAsync(string url, UserTrackSortBy trackQuery, int offset = 0, int limit = 50, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetTrackBatchesAsync>d__7(-2) { <>4__this = this, <>3__url = url, <>3__trackQuery = trackQuery, <>3__offset = offset, <>3__limit = limit, <>3__cancellationToken = cancellationToken }; } public IAsyncEnumerable<Track> GetTracksAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetTrackBatchesAsync(url, UserTrackSortBy.Default, offset, limit, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Track> GetTracksAsync(string url, CancellationToken cancellationToken) { return GetTrackBatchesAsync(url, UserTrackSortBy.Default, 0, 50, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Track> GetPopularTracksAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetTrackBatchesAsync(url, UserTrackSortBy.Popular, offset, limit, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Track> GetPopularTracksAsync(string url, CancellationToken cancellationToken) { return GetTrackBatchesAsync(url, UserTrackSortBy.Popular, 0, 50, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Track> GetLikedTracksAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetTrackBatchesAsync(url, UserTrackSortBy.Likes, offset, limit, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Track> GetLikedTracksAsync(string url, CancellationToken cancellationToken) { return GetTrackBatchesAsync(url, UserTrackSortBy.Likes, 0, 50, cancellationToken).FlattenAsync(); } [AsyncIteratorStateMachine(typeof(<GetPlaylistBatchesAsync>d__14))] public IAsyncEnumerable<Batch<Playlist>> GetPlaylistBatchesAsync(string url, int offset = 0, int limit = 50, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetPlaylistBatchesAsync>d__14(-2) { <>4__this = this, <>3__url = url, <>3__offset = offset, <>3__limit = limit, <>3__cancellationToken = cancellationToken }; } public IAsyncEnumerable<Playlist> GetPlaylistsAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetPlaylistBatchesAsync(url, offset, limit, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Playlist> GetPlaylistsAsync(string url, CancellationToken cancellationToken) { return GetPlaylistBatchesAsync(url, 0, 50, cancellationToken).FlattenAsync(); } [AsyncIteratorStateMachine(typeof(<GetAlbumBatchesAsync>d__17))] public IAsyncEnumerable<Batch<Playlist>> GetAlbumBatchesAsync(string url, int offset = 0, int limit = 50, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetAlbumBatchesAsync>d__17(-2) { <>4__this = this, <>3__url = url, <>3__offset = offset, <>3__limit = limit, <>3__cancellationToken = cancellationToken }; } public IAsyncEnumerable<Playlist> GetAlbumsAsync(string url, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetAlbumBatchesAsync(url, offset, limit, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<Playlist> GetAlbumsAsync(string url, CancellationToken cancellationToken) { return GetAlbumBatchesAsync(url, 0, 50, cancellationToken).FlattenAsync(); } } public enum UserTrackSortBy { Default, Popular, Likes } } namespace SoundCloudExplode.Tracks { public class Format { [JsonProperty("protocol")] public string? Protocol { get; set; } [JsonProperty("mime_type")] public string? MimeType { get; set; } } public interface ITrackClient { Task<bool> IsUrlValidAsync(string url, CancellationToken cancellationToken = default(CancellationToken)); ValueTask<Track?> GetAsync(string url, CancellationToken cancellationToken = default(CancellationToken)); ValueTask<string?> GetUrlByIdAsync(long trackId, CancellationToken cancellationToken = default(CancellationToken)); ValueTask<Track?> GetByIdAsync(long trackId, CancellationToken cancellationToken = default(CancellationToken)); ValueTask<string?> GetDownloadUrlAsync(string url, CancellationToken cancellationToken = default(CancellationToken)); ValueTask<string?> GetDownloadUrlAsync(Track track, CancellationToken cancellationToken = default(CancellationToken)); } public class Media { [JsonProperty("transcodings")] public List<Transcoding> Transcodings { get; set; } = new List<Transcoding>(); } public class PublisherMetadata { [JsonProperty("id")] public long? Id { get; set; } [JsonProperty("urn")] public string? Urn { get; set; } [JsonProperty("artist")] public string? Artist { get; set; } [JsonProperty("contains_music")] public bool ContainsMusic { get; set; } } public class Track : IBatchItem { [JsonProperty("artwork_url")] public Uri? ArtworkUrl { get; set; } [JsonProperty("caption")] public object? Caption { get; set; } [JsonProperty("commentable")] public bool Commentable { get; set; } [JsonProperty("comment_count")] public long? CommentCount { get; set; } [JsonProperty("created_at")] public DateTimeOffset CreatedAt { get; set; } [JsonProperty("description")] public string? Description { get; set; } [JsonProperty("downloadable")] public bool Downloadable { get; set; } [JsonProperty("download_count")] public long? DownloadCount { get; set; } [JsonProperty("duration")] public long? Duration { get; set; } [JsonProperty("full_duration")] public long? FullDuration { get; set; } [JsonProperty("embeddable_by")] public string? EmbeddableBy { get; set; } [JsonProperty("genre")] public string? Genre { get; set; } [JsonProperty("has_downloads_left")] public bool HasDownloadsLeft { get; set; } [JsonProperty("id")] public long Id { get; set; } = 0L; [JsonProperty("kind")] public Kind Kind { get; set; } [JsonProperty("label_name")] public string? LabelName { get; set; } [JsonProperty("last_modified")] public DateTimeOffset LastModified { get; set; } [JsonProperty("license")] public string? License { get; set; } [JsonProperty("likes_count")] public long? LikesCount { get; set; } [JsonProperty("permalink")] public string? Permalink { get; set; } [JsonProperty("permalink_url")] public Uri? PermalinkUrl { get; set; } [JsonProperty("playback_count")] public long? PlaybackCount { get; set; } [JsonProperty("public")] public bool Public { get; set; } [JsonProperty("publisher_metadata")] public PublisherMetadata? PublisherMetadata { get; set; } [JsonProperty("purchase_title")] public string? PurchaseTitle { get; set; } [JsonProperty("purchase_url")] public string? PurchaseUrl { get; set; } [JsonProperty("release_date")] public object? ReleaseDate { get; set; } [JsonProperty("reposts_count")] public long? RepostsCount { get; set; } [JsonProperty("secret_token")] public string? SecretToken { get; set; } [JsonProperty("sharing")] public string? Sharing { get; set; } [JsonProperty("state")] public string? State { get; set; } [JsonProperty("streamable")] public bool Streamable { get; set; } [JsonProperty("tag_list")] public string? TagList { get; set; } [JsonProperty("title")] public string? Title { get; set; } [JsonProperty("uri")] public Uri? Uri { get; set; } [JsonProperty("urn")] public string? Urn { get; set; } [JsonProperty("user_id")] public long? UserId { get; set; } [JsonProperty("visuals")] public object? Visuals { get; set; } [JsonProperty("waveform_url")] public string? WaveformUrl { get; set; } [JsonProperty("display_date")] public DateTimeOffset DisplayDate { get; set; } [JsonProperty("media")] public Media? Media { get; set; } [JsonProperty("monetization_model")] public string? MonetizationModel { get; set; } [JsonProperty("policy")] public string? Policy { get; set; } [JsonProperty("user")] public User? User { get; set; } public string? PlaylistName { get; set; } [ExcludeFromCodeCoverage] public override string ToString() { return "Track (" + Title + ")"; } } public class TrackClient : ITrackClient { [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpClient <http>P; [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private SoundcloudEndpoint <endpoint>P; private readonly Regex ShortUrlRegex; private readonly Regex SingleTrackRegex; private readonly Regex TracksRegex; public TrackClient(HttpClient http, SoundcloudEndpoint endpoint) { <http>P = http; <endpoint>P = endpoint; ShortUrlRegex = new Regex("on\\.soundcloud\\..+?\\/.+?"); SingleTrackRegex = new Regex("soundcloud\\..+?\\/(.*?)\\/[a-zA-Z0-9~@#$^*()_+=[\\]{}|\\\\,.?: -]+"); TracksRegex = new Regex("soundcloud\\..+?\\/(.*?)\\/track"); base..ctor(); } public async Task<bool> IsUrlValidAsync(string url, CancellationToken cancellationToken = default(CancellationToken)) { if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { return false; } url = url.ToLower(); if (ShortUrlRegex.IsMatch(url)) { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url); using HttpResponseMessage response = await <http>P.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); url = response.RequestMessage.RequestUri.ToString(); } return TracksRegex.IsMatch(url) || SingleTrackRegex.IsMatch(url); } public async ValueTask<Track?> GetAsync(string url, CancellationToken cancellationToken = default(CancellationToken)) { if (!(await IsUrlValidAsync(url, cancellationToken))) { throw new SoundcloudExplodeException("Invalid track url"); } return JsonConvert.DeserializeObject<Track>(await <endpoint>P.ResolveUrlAsync(url, cancellationToken), JsonSettings.Default); } public async ValueTask<string?> GetUrlByIdAsync(long trackId, CancellationToken cancellationToken = default(CancellationToken)) { string trackInfoJson = await <http>P.ExecuteGetAsync(string.Format("{0}/{1}?client_id={2}", "https://api-v2.soundcloud.com/tracks", trackId, <endpoint>P.ClientId), cancellationToken); if (trackInfoJson == null) { return null; } Track track = JsonConvert.DeserializeObject<Track>(trackInfoJson, JsonSettings.Default); return (track == null || (object)track.PermalinkUrl == null) ? null : track.PermalinkUrl?.ToString(); } public async ValueTask<Track?> GetByIdAsync(long trackId, CancellationToken cancellationToken = default(CancellationToken)) { string trackUrl = await GetUrlByIdAsync(trackId, cancellationToken); return (trackUrl != null) ? (await GetAsync(trackUrl, cancellationToken)) : null; } private async ValueTask<string?> QueryTrackMp3Async(string trackM3u8, CancellationToken cancellationToken = default(CancellationToken)) { string[] m3u8 = (await <http>P.ExecuteGetAsync(trackM3u8, cancellationToken)).Split(new char[1] { ',' }); if (m3u8.Length == 0) { return null; } string link = ""; string[] last_stream = m3u8.Last().Split(new char[1] { '/' }); for (int i = 0; i < last_stream.Length; i++) { if (last_stream[i] == "media") { last_stream[i + 1] = "0"; link = string.Join("/", last_stream).Split(new char[1] { '\n' })[1]; } } return link; } public async ValueTask<string?> GetDownloadUrlAsync(string url, CancellationToken cancellationToken = default(CancellationToken)) { Track track = await GetAsync(url, cancellationToken); if (track == null) { return null; } return await GetDownloadUrlAsync(track, cancellationToken); } public async ValueTask<string?> GetDownloadUrlAsync(Track track, CancellationToken cancellationToken = default(CancellationToken)) { if (track.Policy?.ToLower() == "block") { throw new TrackUnavailableException("This track is not available in your country"); } if (track.Media == null || track.Media.Transcodings == null || track.Media.Transcodings.Count == 0) { throw new TrackUnavailableException("No transcodings found"); } Transcoding transcoding = track.Media.Transcodings.FirstOrDefault(delegate(Transcoding x) { int result4; if (x.Quality == "hq") { Format? format4 = x.Format; if (format4 != null && (format4.MimeType?.Contains("audio/mp4")).GetValueOrDefault()) { result4 = ((x.Format.Protocol == "progressive") ? 1 : 0); goto IL_0064; } } result4 = 0; goto IL_0064; IL_0064: return (byte)result4 != 0; }) ?? track.Media.Transcodings.FirstOrDefault(delegate(Transcoding x) { int result3; if (x.Quality == "hq") { Format? format3 = x.Format; if (format3 != null && (format3.MimeType?.Contains("audio/mp4")).GetValueOrDefault()) { result3 = ((x.Format.Protocol == "hls") ? 1 : 0); goto IL_0064; } } result3 = 0; goto IL_0064; IL_0064: return (byte)result3 != 0; }) ?? track.Media.Transcodings.FirstOrDefault(delegate(Transcoding x) { int result2; if (x.Quality == "sq") { Format? format2 = x.Format; if (format2 != null && (format2.MimeType?.Contains("audio/mpeg")).GetValueOrDefault()) { result2 = ((x.Format.Protocol == "progressive") ? 1 : 0); goto IL_0064; } } result2 = 0; goto IL_0064; IL_0064: return (byte)result2 != 0; }) ?? track.Media.Transcodings.FirstOrDefault(delegate(Transcoding x) { int result; if (x.Quality == "sq") { Format? format = x.Format; if (format != null && (format.MimeType?.Contains("ogg")).GetValueOrDefault()) { result = ((x.Format.Protocol == "hls") ? 1 : 0); goto IL_0064; } } result = 0; goto IL_0064; IL_0064: return (byte)result != 0; }); if (transcoding == null || (object)transcoding.Url == null) { return null; } JObject jObject = JObject.Parse(await HttpExtensions.ExecuteGetAsync(url: transcoding.Url.ToString() + "?client_id=" + <endpoint>P.ClientId, http: <http>P, cancellationToken: cancellationToken)); string trackMediaUrl = ((object)jObject["url"])?.ToString(); return (!(trackMediaUrl?.Contains(".m3u8") ?? false)) ? trackMediaUrl : (await QueryTrackMp3Async(trackMediaUrl, cancellationToken)); } } public class Transcoding { [JsonProperty("url")] public Uri? Url { get; set; } [JsonProperty("preset")] public string? Preset { get; set; } [JsonProperty("duration")] public long? Duration { get; set; } [JsonProperty("snipped")] public bool Snipped { get; set; } [JsonProperty("format")] public Format? Format { get; set; } [JsonProperty("quality")] public string? Quality { get; set; } } } namespace SoundCloudExplode.Search { public interface ISearchClient { bool IsUrlValid(string url); ValueTask<List<string>> GetSearchQueriesAsync(string query, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<Batch<ISearchResult>> GetResultBatchesAsync(string searchQuery, SearchFilter searchFilter, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<ISearchResult> GetResultsAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<TrackSearchResult> GetTracksAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<PlaylistSearchResult> GetPlaylistsAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<PlaylistSearchResult> GetPlaylistsWithoutAlbumsAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<PlaylistSearchResult> GetAlbumsAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); IAsyncEnumerable<UserSearchResult> GetUsersAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)); } public interface ISearchResult : IBatchItem { string? Url { get; } string? Title { get; } } public class PlaylistSearchResult : Playlist, ISearchResult, IBatchItem { public string? Url => base.PermalinkUrl?.ToString(); } public class SearchClient : ISearchClient { [CompilerGenerated] private sealed class <GetResultBatchesAsync>d__5 : IAsyncEnumerable<Batch<ISearchResult>>, IAsyncEnumerator<Batch<ISearchResult>>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private Batch<ISearchResult> <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; private string searchQuery; public string <>3__searchQuery; private SearchFilter searchFilter; public SearchFilter <>3__searchFilter; private int offset; public int <>3__offset; private int limit; public int <>3__limit; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; public SearchClient <>4__this; private HashSet<string> <encounteredUrls>5__1; private int <continuationOffset>5__2; private List<ISearchResult> <results>5__3; private string <searchFilterStr>5__4; private string <url>5__5; private string <response>5__6; private JObject <jObject>5__7; private JToken <collection>5__8; private string <>s__9; private IEnumerator<JToken> <>s__10; private JToken <item>5__11; private string <permalinkUrl>5__12; private Uri <permalinkUri>5__13; private UserSearchResult <user>5__14; private TrackSearchResult <track>5__15; private PlaylistSearchResult <playlist>5__16; private ValueTaskAwaiter<string> <>u__1; Batch<ISearchResult> IAsyncEnumerator<Batch<ISearchResult>>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetResultBatchesAsync>d__5(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; try { ValueTaskAwaiter<string> awaiter; switch (num) { default: if (!<>w__disposeMode) { num = (<>1__state = -1); Limitor.Validate(limit); <encounteredUrls>5__1 = new HashSet<string>(StringComparer.Ordinal); <continuationOffset>5__2 = offset; <results>5__3 = new List<ISearchResult>(); if (1 == 0) { } string text = searchFilter switch { SearchFilter.Track => "/tracks", SearchFilter.Playlist => "/playlists", SearchFilter.PlaylistWithoutAlbums => "/playlists_without_albums", SearchFilter.Album => "/albums", SearchFilter.User => "/users", _ => "", }; if (1 == 0) { } <searchFilterStr>5__4 = text; goto IL_049f; } goto end_IL_0007; case 0: awaiter = <>u__1; <>u__1 = default(ValueTaskAwaiter<string>); num = (<>1__state = -1); break; case -4: { num = (<>1__state = -1); if (!<>w__disposeMode) { <continuationOffset>5__2 += <results>5__3.Count; <url>5__5 = null; <response>5__6 = null; <jObject>5__7 = null; <collection>5__8 = null; goto IL_049f; } goto end_IL_0007; } IL_049f: <results>5__3.Clear(); <url>5__5 = $"https://api-v2.soundcloud.com/search{<searchFilterStr>5__4}?q={Uri.EscapeDataString(searchQuery)}&client_id={<>4__this.<endpoint>P.ClientId}&limit={limit}&offset={<continuationOffset>5__2}"; <>2__current = null; awaiter = <>4__this.<http>P.ExecuteGetAsync(<url>5__5, cancellationToken).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetResultBatchesAsync>d__5 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } break; } <>s__9 = awaiter.GetResult(); <response>5__6 = <>s__9; <>s__9 = null; <jObject>5__7 = JObject.Parse(<response>5__6); <collection>5__8 = <jObject>5__7["collection"]; if (<collection>5__8 != null && ((IEnumerable<JToken>)<collection>5__8).Any()) { <>s__10 = ((IEnumerable<JToken>)<collection>5__8).GetEnumerator(); try { while (<>s__10.MoveNext()) { <item>5__11 = <>s__10.Current; <permalinkUrl>5__12 = ((object)<item>5__11[(object)"permalink_url"])?.ToString(); if (<permalinkUrl>5__12 == null || !Uri.IsWellFormedUriString(<permalinkUrl>5__12, UriKind.Absolute) || !<encounteredUrls>5__1.Add(<permalinkUrl>5__12)) { continue; } <permalinkUri>5__13 = new Uri(<permalinkUrl>5__12); if (<permalinkUri>5__13.Segments.Length == 2) { <user>5__14 = JsonConvert.DeserializeObject<UserSearchResult>(((object)<item>5__11).ToString(), JsonSettings.Default); <results>5__3.Add(<user>5__14); continue; } if (<permalinkUri>5__13.Segments.Length == 3) { <track>5__15 = JsonConvert.DeserializeObject<TrackSearchResult>(((object)<item>5__11).ToString(), JsonSettings.Default); <results>5__3.Add(<track>5__15); continue; } if (<permalinkUri>5__13.Segments.Length == 4 && <permalinkUri>5__13.Segments[2] == "sets/") { <playlist>5__16 = JsonConvert.DeserializeObject<PlaylistSearchResult>(((object)<item>5__11).ToString(), JsonSettings.Default); <results>5__3.Add(<playlist>5__16); <playlist>5__16 = null; } <permalinkUrl>5__12 = null; <permalinkUri>5__13 = null; <item>5__11 = null; } } finally { if (num == -1 && <>s__10 != null) { <>s__10.Dispose(); } } if (!<>w__disposeMode) { <>s__10 = null; if (<results>5__3.Count != 0) { <>2__current = Batch.Create(<results>5__3); num = (<>1__state = -4); goto IL_060d; } } } end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <encounteredUrls>5__1 = null; <results>5__3 = null; <searchFilterStr>5__4 = null; <url>5__5 = null; <response>5__6 = null; <jObject>5__7 = null; <collection>5__8 = null; <>s__9 = null; <>s__10 = null; <item>5__11 = null; <permalinkUrl>5__12 = null; <permalinkUri>5__13 = null; <user>5__14 = null; <track>5__15 = null; <playlist>5__16 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <encounteredUrls>5__1 = null; <results>5__3 = null; <searchFilterStr>5__4 = null; <url>5__5 = null; <response>5__6 = null; <jObject>5__7 = null; <collection>5__8 = null; <>s__9 = null; <>s__10 = null; <item>5__11 = null; <permalinkUrl>5__12 = null; <permalinkUri>5__13 = null; <user>5__14 = null; <track>5__15 = null; <playlist>5__16 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_060d: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<Batch<ISearchResult>> IAsyncEnumerable<Batch<ISearchResult>>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetResultBatchesAsync>d__5 <GetResultBatchesAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetResultBatchesAsync>d__ = this; } else { <GetResultBatchesAsync>d__ = new <GetResultBatchesAsync>d__5(-3) { <>4__this = <>4__this }; } <GetResultBatchesAsync>d__.searchQuery = <>3__searchQuery; <GetResultBatchesAsync>d__.searchFilter = <>3__searchFilter; <GetResultBatchesAsync>d__.offset = <>3__offset; <GetResultBatchesAsync>d__.limit = <>3__limit; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetResultBatchesAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetResultBatchesAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetResultBatchesAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetResultBatchesAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<Batch<ISearchResult>>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetResultBatchesAsync>d__5 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetResultBatchesAsync>d__5 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpClient <http>P; [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private SoundcloudEndpoint <endpoint>P; public SearchClient(HttpClient http, SoundcloudEndpoint endpoint) { <http>P = http; <endpoint>P = endpoint; base..ctor(); } public bool IsUrlValid(string url) { url = url.ToLower(); return Uri.IsWellFormedUriString(url, UriKind.Absolute); } public async ValueTask<List<string>> GetSearchQueriesAsync(string query, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(query)) { return new List<string>(); } Limitor.Validate(limit); JObject jObject = JObject.Parse(await HttpExtensions.ExecuteGetAsync(url: $"https://api-v2.soundcloud.com/search/queries?q={Uri.EscapeDataString(query)}&client_id=Tl7CY6xVpYugZsGNqmzUhDCRX3urIPNv&limit={limit}&offset={offset}&linked_partitioning=1&app_version=1718276310&app_locale=en", http: <http>P, cancellationToken: cancellationToken)); return ((IEnumerable<JToken>)jObject["collection"]).Select((JToken x) => ((object)x[(object)"output"]).ToString()).ToList(); } [AsyncIteratorStateMachine(typeof(<GetResultBatchesAsync>d__5))] public IAsyncEnumerable<Batch<ISearchResult>> GetResultBatchesAsync(string searchQuery, SearchFilter searchFilter, int offset = 0, int limit = 50, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetResultBatchesAsync>d__5(-2) { <>4__this = this, <>3__searchQuery = searchQuery, <>3__searchFilter = searchFilter, <>3__offset = offset, <>3__limit = limit, <>3__cancellationToken = cancellationToken }; } public IAsyncEnumerable<Batch<ISearchResult>> GetResultBatchesAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, SearchFilter.None, offset, limit, cancellationToken); } public IAsyncEnumerable<Batch<ISearchResult>> GetResultBatchesAsync(string searchQuery, CancellationToken cancellationToken) { return GetResultBatchesAsync(searchQuery, SearchFilter.None, 0, 50, cancellationToken); } public IAsyncEnumerable<ISearchResult> GetResultsAsync(string searchQuery, int offset = 0, int limit = 50, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, offset, limit, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<ISearc
System.Runtime.CompilerServices.Unsafe.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: AssemblyProduct("Microsoft® .NET Framework")] [assembly: CLSCompliant(false)] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")] [assembly: AssemblyFileVersion("6.100.225.20307")] [assembly: AssemblyInformationalVersion("6.1.2")] [assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyVersion("6.0.3.0")] namespace System.Runtime.CompilerServices { public static class Unsafe { [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static T Read<T>(void* source) { return Unsafe.Read<T>(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static T ReadUnaligned<T>(void* source) { return Unsafe.ReadUnaligned<T>(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static T ReadUnaligned<T>(ref byte source) { return Unsafe.ReadUnaligned<T>(ref source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void Write<T>(void* destination, T value) { Unsafe.Write(destination, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void WriteUnaligned<T>(void* destination, T value) { Unsafe.WriteUnaligned(destination, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void WriteUnaligned<T>(ref byte destination, T value) { Unsafe.WriteUnaligned(ref destination, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void Copy<T>(void* destination, ref T source) { Unsafe.Write(destination, source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void Copy<T>(ref T destination, void* source) { destination = Unsafe.Read<T>(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void* AsPointer<T>(ref T value) { return Unsafe.AsPointer(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void SkipInit<T>(out T value) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static int SizeOf<T>() { return Unsafe.SizeOf<T>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlock(destination, source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlock(ref destination, ref source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlockUnaligned(destination, source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlock(startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void InitBlock(ref byte startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlock(ref startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlockUnaligned(startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static T As<T>(object o) where T : class { return (T)o; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static ref T AsRef<T>(void* source) { return ref *(T*)source; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T AsRef<T>(in T source) { return ref source; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref TTo As<TFrom, TTo>(ref TFrom source) { return ref Unsafe.As<TFrom, TTo>(ref source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Unbox<T>(object box) where T : struct { return ref (T)box; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Add<T>(ref T source, int elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void* Add<T>(void* source, int elementOffset) { return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Add<T>(ref T source, IntPtr elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T Add<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset) { return ref Unsafe.AddByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T AddByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset) { return ref Unsafe.AddByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Subtract<T>(ref T source, int elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void* Subtract<T>(void* source, int elementOffset) { return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Subtract<T>(ref T source, IntPtr elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T Subtract<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset) { return ref Unsafe.SubtractByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T SubtractByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset) { return ref Unsafe.SubtractByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static IntPtr ByteOffset<T>(ref T origin, ref T target) { return Unsafe.ByteOffset(target: ref target, origin: ref origin); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static bool AreSame<T>(ref T left, ref T right) { return Unsafe.AreSame(ref left, ref right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static bool IsAddressGreaterThan<T>(ref T left, ref T right) { return Unsafe.IsAddressGreaterThan(ref left, ref right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static bool IsAddressLessThan<T>(ref T left, ref T right) { return Unsafe.IsAddressLessThan(ref left, ref right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static bool IsNullRef<T>(ref T source) { return Unsafe.AsPointer(ref source) == null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static ref T NullRef<T>() { return ref *(T*)null; } } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class NonVersionableAttribute : Attribute { } } namespace System.Runtime.CompilerServices { internal sealed class IsReadOnlyAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] A_0) { TransformFlags = A_0; } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } }
System.Threading.Tasks.Extensions.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using System.Threading.Tasks.Sources; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: CLSCompliant(true)] [assembly: AssemblyDefaultAlias("System.Threading.Tasks.Extensions")] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("System.Threading.Tasks.Extensions")] [assembly: AssemblyFileVersion("4.600.325.20307")] [assembly: AssemblyInformationalVersion("4.6.3+f62ca0009b038cab4725a720f386623a969d73ad")] [assembly: AssemblyProduct("Microsoft® .NET")] [assembly: AssemblyTitle("System.Threading.Tasks.Extensions")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/maintenance-packages")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.2.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [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 System { internal static class ThrowHelper { internal static void ThrowArgumentNullException(System.ExceptionArgument argument) { throw GetArgumentNullException(argument); } internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument) { throw GetArgumentOutOfRangeException(argument); } private static ArgumentNullException GetArgumentNullException(System.ExceptionArgument argument) { return new ArgumentNullException(GetArgumentName(argument)); } private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(System.ExceptionArgument argument) { return new ArgumentOutOfRangeException(GetArgumentName(argument)); } [MethodImpl(MethodImplOptions.NoInlining)] private static string GetArgumentName(System.ExceptionArgument argument) { return argument.ToString(); } } internal enum ExceptionArgument { task, source, state } } namespace System.Threading.Tasks { [StructLayout(LayoutKind.Auto)] [AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder))] public readonly struct ValueTask : IEquatable<ValueTask> { private sealed class ValueTaskSourceAsTask : TaskCompletionSource<bool> { private static readonly Action<object> s_completionAction = delegate(object state) { if (state is ValueTaskSourceAsTask valueTaskSourceAsTask) { IValueTaskSource source = valueTaskSourceAsTask._source; if (source != null) { valueTaskSourceAsTask._source = null; ValueTaskSourceStatus status = source.GetStatus(valueTaskSourceAsTask._token); try { source.GetResult(valueTaskSourceAsTask._token); valueTaskSourceAsTask.TrySetResult(result: false); return; } catch (Exception exception) { if (status == ValueTaskSourceStatus.Canceled) { valueTaskSourceAsTask.TrySetCanceled(); } else { valueTaskSourceAsTask.TrySetException(exception); } return; } } } System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state); }; private IValueTaskSource _source; private readonly short _token; public ValueTaskSourceAsTask(IValueTaskSource source, short token) { _token = token; _source = source; source.OnCompleted(s_completionAction, this, token, ValueTaskSourceOnCompletedFlags.None); } } private static readonly Task s_canceledTask = Task.FromCanceled(new CancellationToken(canceled: true)); internal readonly object _obj; internal readonly short _token; internal readonly bool _continueOnCapturedContext; internal static Task CompletedTask => Task.CompletedTask; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) { return true; } if (obj is Task task) { return task.IsCompleted; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) != ValueTaskSourceStatus.Pending; } } public bool IsCompletedSuccessfully { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) { return true; } if (obj is Task task) { return task.Status == TaskStatus.RanToCompletion; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded; } } public bool IsFaulted { get { object obj = _obj; if (obj == null) { return false; } if (obj is Task task) { return task.IsFaulted; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Faulted; } } public bool IsCanceled { get { object obj = _obj; if (obj == null) { return false; } if (obj is Task task) { return task.IsCanceled; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Canceled; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(Task task) { if (task == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.task); } _obj = task; _continueOnCapturedContext = true; _token = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(IValueTaskSource source, short token) { if (source == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.source); } _obj = source; _token = token; _continueOnCapturedContext = true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ValueTask(object obj, short token, bool continueOnCapturedContext) { _obj = obj; _token = token; _continueOnCapturedContext = continueOnCapturedContext; } public override int GetHashCode() { return _obj?.GetHashCode() ?? 0; } public override bool Equals(object obj) { if (obj is ValueTask) { return Equals((ValueTask)obj); } return false; } public bool Equals(ValueTask other) { if (_obj == other._obj) { return _token == other._token; } return false; } public static bool operator ==(ValueTask left, ValueTask right) { return left.Equals(right); } public static bool operator !=(ValueTask left, ValueTask right) { return !left.Equals(right); } public Task AsTask() { object obj = _obj; object obj2; if (obj != null) { obj2 = obj as Task; if (obj2 == null) { return GetTaskForValueTaskSource(System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj)); } } else { obj2 = CompletedTask; } return (Task)obj2; } public ValueTask Preserve() { if (_obj != null) { return new ValueTask(AsTask()); } return this; } private Task GetTaskForValueTaskSource(IValueTaskSource t) { ValueTaskSourceStatus status = t.GetStatus(_token); if (status != 0) { try { t.GetResult(_token); return CompletedTask; } catch (Exception exception) { if (status == ValueTaskSourceStatus.Canceled) { return s_canceledTask; } TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>(); taskCompletionSource.TrySetException(exception); return taskCompletionSource.Task; } } ValueTaskSourceAsTask valueTaskSourceAsTask = new ValueTaskSourceAsTask(t, _token); return valueTaskSourceAsTask.Task; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [StackTraceHidden] internal void ThrowIfCompletedUnsuccessfully() { object obj = _obj; if (obj != null) { if (obj is Task task) { task.GetAwaiter().GetResult(); } else { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetResult(_token); } } } public ValueTaskAwaiter GetAwaiter() { return new ValueTaskAwaiter(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) { return new ConfiguredValueTaskAwaitable(new ValueTask(_obj, _token, continueOnCapturedContext)); } } [StructLayout(LayoutKind.Auto)] [AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder<>))] public readonly struct ValueTask<TResult> : IEquatable<ValueTask<TResult>> { private sealed class ValueTaskSourceAsTask : TaskCompletionSource<TResult> { private static readonly Action<object> s_completionAction = delegate(object state) { if (state is ValueTaskSourceAsTask valueTaskSourceAsTask) { IValueTaskSource<TResult> source = valueTaskSourceAsTask._source; if (source != null) { valueTaskSourceAsTask._source = null; ValueTaskSourceStatus status = source.GetStatus(valueTaskSourceAsTask._token); try { valueTaskSourceAsTask.TrySetResult(source.GetResult(valueTaskSourceAsTask._token)); return; } catch (Exception exception) { if (status == ValueTaskSourceStatus.Canceled) { valueTaskSourceAsTask.TrySetCanceled(); } else { valueTaskSourceAsTask.TrySetException(exception); } return; } } } System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state); }; private IValueTaskSource<TResult> _source; private readonly short _token; public ValueTaskSourceAsTask(IValueTaskSource<TResult> source, short token) { _source = source; _token = token; source.OnCompleted(s_completionAction, this, token, ValueTaskSourceOnCompletedFlags.None); } } private static Task<TResult> s_canceledTask; internal readonly object _obj; internal readonly TResult _result; internal readonly short _token; internal readonly bool _continueOnCapturedContext; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) { return true; } if (obj is Task<TResult> task) { return task.IsCompleted; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) != ValueTaskSourceStatus.Pending; } } public bool IsCompletedSuccessfully { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) { return true; } if (obj is Task<TResult> task) { return task.Status == TaskStatus.RanToCompletion; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded; } } public bool IsFaulted { get { object obj = _obj; if (obj == null) { return false; } if (obj is Task<TResult> task) { return task.IsFaulted; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Faulted; } } public bool IsCanceled { get { object obj = _obj; if (obj == null) { return false; } if (obj is Task<TResult> task) { return task.IsCanceled; } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Canceled; } } public TResult Result { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) { return _result; } if (obj is Task<TResult> task) { return task.GetAwaiter().GetResult(); } return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetResult(_token); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(TResult result) { _result = result; _obj = null; _continueOnCapturedContext = true; _token = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(Task<TResult> task) { if (task == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.task); } _obj = task; _result = default(TResult); _continueOnCapturedContext = true; _token = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(IValueTaskSource<TResult> source, short token) { if (source == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.source); } _obj = source; _token = token; _result = default(TResult); _continueOnCapturedContext = true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ValueTask(object obj, TResult result, short token, bool continueOnCapturedContext) { _obj = obj; _result = result; _token = token; _continueOnCapturedContext = continueOnCapturedContext; } public override int GetHashCode() { if (_obj == null) { if (_result == null) { return 0; } return _result.GetHashCode(); } return _obj.GetHashCode(); } public override bool Equals(object obj) { if (obj is ValueTask<TResult>) { return Equals((ValueTask<TResult>)obj); } return false; } public bool Equals(ValueTask<TResult> other) { if (_obj == null && other._obj == null) { return EqualityComparer<TResult>.Default.Equals(_result, other._result); } if (_obj == other._obj) { return _token == other._token; } return false; } public static bool operator ==(ValueTask<TResult> left, ValueTask<TResult> right) { return left.Equals(right); } public static bool operator !=(ValueTask<TResult> left, ValueTask<TResult> right) { return !left.Equals(right); } public Task<TResult> AsTask() { object obj = _obj; if (obj == null) { return Task.FromResult(_result); } if (obj is Task<TResult> result) { return result; } return GetTaskForValueTaskSource(System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj)); } public ValueTask<TResult> Preserve() { if (_obj != null) { return new ValueTask<TResult>(AsTask()); } return this; } private Task<TResult> GetTaskForValueTaskSource(IValueTaskSource<TResult> t) { ValueTaskSourceStatus status = t.GetStatus(_token); if (status != 0) { try { return Task.FromResult(t.GetResult(_token)); } catch (Exception exception) { if (status == ValueTaskSourceStatus.Canceled) { Task<TResult> task = s_canceledTask; if (task == null) { TaskCompletionSource<TResult> taskCompletionSource = new TaskCompletionSource<TResult>(); taskCompletionSource.TrySetCanceled(); task = (s_canceledTask = taskCompletionSource.Task); } return task; } TaskCompletionSource<TResult> taskCompletionSource2 = new TaskCompletionSource<TResult>(); taskCompletionSource2.TrySetException(exception); return taskCompletionSource2.Task; } } ValueTaskSourceAsTask valueTaskSourceAsTask = new ValueTaskSourceAsTask(t, _token); return valueTaskSourceAsTask.Task; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTaskAwaiter<TResult> GetAwaiter() { return new ValueTaskAwaiter<TResult>(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ConfiguredValueTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext) { return new ConfiguredValueTaskAwaitable<TResult>(new ValueTask<TResult>(_obj, _result, _token, continueOnCapturedContext)); } public override string ToString() { if (IsCompletedSuccessfully) { TResult result = Result; if (result != null) { return result.ToString(); } } return string.Empty; } } } namespace System.Threading.Tasks.Sources { [Flags] public enum ValueTaskSourceOnCompletedFlags { None = 0, UseSchedulingContext = 1, FlowExecutionContext = 2 } public enum ValueTaskSourceStatus { Pending, Succeeded, Faulted, Canceled } public interface IValueTaskSource { ValueTaskSourceStatus GetStatus(short token); void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags); void GetResult(short token); } public interface IValueTaskSource<out TResult> { ValueTaskSourceStatus GetStatus(short token); void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags); TResult GetResult(short token); } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)] public sealed class AsyncMethodBuilderAttribute : Attribute { public Type BuilderType { get; } public AsyncMethodBuilderAttribute(Type builderType) { BuilderType = builderType; } } [StructLayout(LayoutKind.Auto)] public struct AsyncValueTaskMethodBuilder { private AsyncTaskMethodBuilder _methodBuilder; private bool _haveResult; private bool _useBuilder; public ValueTask Task { get { if (_haveResult) { return default(ValueTask); } _useBuilder = true; return new ValueTask(_methodBuilder.Task); } } public static AsyncValueTaskMethodBuilder Create() { return default(AsyncValueTaskMethodBuilder); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { _methodBuilder.Start(ref stateMachine); } public void SetStateMachine(IAsyncStateMachine stateMachine) { _methodBuilder.SetStateMachine(stateMachine); } public void SetResult() { if (_useBuilder) { _methodBuilder.SetResult(); } else { _haveResult = true; } } public void SetException(Exception exception) { _methodBuilder.SetException(exception); } public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { _useBuilder = true; _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine); } [SecuritySafeCritical] public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { _useBuilder = true; _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); } } [StructLayout(LayoutKind.Auto)] public struct AsyncValueTaskMethodBuilder<TResult> { private AsyncTaskMethodBuilder<TResult> _methodBuilder; private TResult _result; private bool _haveResult; private bool _useBuilder; public ValueTask<TResult> Task { get { if (_haveResult) { return new ValueTask<TResult>(_result); } _useBuilder = true; return new ValueTask<TResult>(_methodBuilder.Task); } } public static AsyncValueTaskMethodBuilder<TResult> Create() { return default(AsyncValueTaskMethodBuilder<TResult>); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { _methodBuilder.Start(ref stateMachine); } public void SetStateMachine(IAsyncStateMachine stateMachine) { _methodBuilder.SetStateMachine(stateMachine); } public void SetResult(TResult result) { if (_useBuilder) { _methodBuilder.SetResult(result); return; } _result = result; _haveResult = true; } public void SetException(Exception exception) { _methodBuilder.SetException(exception); } public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { _useBuilder = true; _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine); } [SecuritySafeCritical] public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { _useBuilder = true; _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); } } [StructLayout(LayoutKind.Auto)] public readonly struct ConfiguredValueTaskAwaitable { [StructLayout(LayoutKind.Auto)] public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion { private readonly ValueTask _value; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _value.IsCompleted; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ConfiguredValueTaskAwaiter(ValueTask value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [StackTraceHidden] public void GetResult() { _value.ThrowIfCompletedUnsuccessfully(); } public void OnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task task) { task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.FlowExecutionContext | (_value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None)); } else { ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation); } } public void UnsafeOnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task task) { task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None); } else { ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation); } } } private readonly ValueTask _value; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ConfiguredValueTaskAwaitable(ValueTask value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ConfiguredValueTaskAwaiter GetAwaiter() { return new ConfiguredValueTaskAwaiter(_value); } } [StructLayout(LayoutKind.Auto)] public readonly struct ConfiguredValueTaskAwaitable<TResult> { [StructLayout(LayoutKind.Auto)] public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion { private readonly ValueTask<TResult> _value; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _value.IsCompleted; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ConfiguredValueTaskAwaiter(ValueTask<TResult> value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [StackTraceHidden] public TResult GetResult() { return _value.Result; } public void OnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task<TResult> task) { task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.FlowExecutionContext | (_value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None)); } else { ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation); } } public void UnsafeOnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task<TResult> task) { task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None); } else { ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation); } } } private readonly ValueTask<TResult> _value; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ConfiguredValueTaskAwaitable(ValueTask<TResult> value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ConfiguredValueTaskAwaiter GetAwaiter() { return new ConfiguredValueTaskAwaiter(_value); } } public readonly struct ValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion { internal static readonly Action<object> s_invokeActionDelegate = delegate(object state) { if (!(state is Action action)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state); } else { action(); } }; private readonly ValueTask _value; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _value.IsCompleted; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ValueTaskAwaiter(ValueTask value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [StackTraceHidden] public void GetResult() { _value.ThrowIfCompletedUnsuccessfully(); } public void OnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task task) { task.GetAwaiter().OnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext); } else { ValueTask.CompletedTask.GetAwaiter().OnCompleted(continuation); } } public void UnsafeOnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task task) { task.GetAwaiter().UnsafeOnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); } else { ValueTask.CompletedTask.GetAwaiter().UnsafeOnCompleted(continuation); } } } public readonly struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion, INotifyCompletion { private readonly ValueTask<TResult> _value; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _value.IsCompleted; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ValueTaskAwaiter(ValueTask<TResult> value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [StackTraceHidden] public TResult GetResult() { return _value.Result; } public void OnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task<TResult> task) { task.GetAwaiter().OnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext); } else { ValueTask.CompletedTask.GetAwaiter().OnCompleted(continuation); } } public void UnsafeOnCompleted(Action continuation) { object obj = _value._obj; if (obj is Task<TResult> task) { task.GetAwaiter().UnsafeOnCompleted(continuation); } else if (obj != null) { System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); } else { ValueTask.CompletedTask.GetAwaiter().UnsafeOnCompleted(continuation); } } } } namespace System.Diagnostics { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)] internal sealed class StackTraceHiddenAttribute : Attribute { } }
System.ValueTuple.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Numerics.Hashing; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using FxResources.System.ValueTuple; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: CLSCompliant(true)] [assembly: AssemblyDefaultAlias("System.ValueTuple")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("System.ValueTuple")] [assembly: AssemblyFileVersion("4.600.125.16908")] [assembly: AssemblyInformationalVersion("4.6.1+6b84308c9ad012f53240d72c1d716d7e42546483")] [assembly: AssemblyProduct("Microsoft® .NET")] [assembly: AssemblyTitle("System.ValueTuple")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/maintenance-packages")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyVersion("4.0.5.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 FxResources.System.ValueTuple { internal static class SR { } } namespace System { public static class TupleExtensions { [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1>(this Tuple<T1> value, out T1 item1) { item1 = value.Item1; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2>(this Tuple<T1, T2> value, out T1 item1, out T2 item2) { item1 = value.Item1; item2 = value.Item2; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3>(this Tuple<T1, T2, T3> value, out T1 item1, out T2 item2, out T3 item3) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4>(this Tuple<T1, T2, T3, T4> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5>(this Tuple<T1, T2, T3, T4, T5> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6>(this Tuple<T1, T2, T3, T4, T5, T6> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7>(this Tuple<T1, T2, T3, T4, T5, T6, T7> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; item16 = value.Rest.Rest.Item2; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; item16 = value.Rest.Rest.Item2; item17 = value.Rest.Rest.Item3; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; item16 = value.Rest.Rest.Item2; item17 = value.Rest.Rest.Item3; item18 = value.Rest.Rest.Item4; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; item16 = value.Rest.Rest.Item2; item17 = value.Rest.Rest.Item3; item18 = value.Rest.Rest.Item4; item19 = value.Rest.Rest.Item5; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; item16 = value.Rest.Rest.Item2; item17 = value.Rest.Rest.Item3; item18 = value.Rest.Rest.Item4; item19 = value.Rest.Rest.Item5; item20 = value.Rest.Rest.Item6; } [EditorBrowsable(EditorBrowsableState.Never)] public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20, out T21 item21) { item1 = value.Item1; item2 = value.Item2; item3 = value.Item3; item4 = value.Item4; item5 = value.Item5; item6 = value.Item6; item7 = value.Item7; item8 = value.Rest.Item1; item9 = value.Rest.Item2; item10 = value.Rest.Item3; item11 = value.Rest.Item4; item12 = value.Rest.Item5; item13 = value.Rest.Item6; item14 = value.Rest.Item7; item15 = value.Rest.Rest.Item1; item16 = value.Rest.Rest.Item2; item17 = value.Rest.Rest.Item3; item18 = value.Rest.Rest.Item4; item19 = value.Rest.Rest.Item5; item20 = value.Rest.Rest.Item6; item21 = value.Rest.Rest.Item7; } public static ValueTuple<T1> ToValueTuple<T1>(this Tuple<T1> value) { return ValueTuple.Create(value.Item1); } public static (T1, T2) ToValueTuple<T1, T2>(this Tuple<T1, T2> value) { return ValueTuple.Create(value.Item1, value.Item2); } public static (T1, T2, T3) ToValueTuple<T1, T2, T3>(this Tuple<T1, T2, T3> value) { return ValueTuple.Create(value.Item1, value.Item2, value.Item3); } public static (T1, T2, T3, T4) ToValueTuple<T1, T2, T3, T4>(this Tuple<T1, T2, T3, T4> value) { return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4); } public static (T1, T2, T3, T4, T5) ToValueTuple<T1, T2, T3, T4, T5>(this Tuple<T1, T2, T3, T4, T5> value) { return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5); } public static (T1, T2, T3, T4, T5, T6) ToValueTuple<T1, T2, T3, T4, T5, T6>(this Tuple<T1, T2, T3, T4, T5, T6> value) { return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6); } public static (T1, T2, T3, T4, T5, T6, T7) ToValueTuple<T1, T2, T3, T4, T5, T6, T7>(this Tuple<T1, T2, T3, T4, T5, T6, T7> value) { return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7); } public static (T1, T2, T3, T4, T5, T6, T7, T8) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value) { return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value) { return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value) { return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value) { return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11, T12)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value) { return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11, T12, T13)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value) { return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11, T12, T13, T14)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7)); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1))); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2))); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3))); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4))); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18, T19)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5))); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18, T19, T20)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6))); } public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value) { return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18, T19, T20, T21)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7))); } public static Tuple<T1> ToTuple<T1>(this ValueTuple<T1> value) { return Tuple.Create(value.Item1); } public static Tuple<T1, T2> ToTuple<T1, T2>(this (T1, T2) value) { return Tuple.Create(value.Item1, value.Item2); } public static Tuple<T1, T2, T3> ToTuple<T1, T2, T3>(this (T1, T2, T3) value) { return Tuple.Create(value.Item1, value.Item2, value.Item3); } public static Tuple<T1, T2, T3, T4> ToTuple<T1, T2, T3, T4>(this (T1, T2, T3, T4) value) { return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4); } public static Tuple<T1, T2, T3, T4, T5> ToTuple<T1, T2, T3, T4, T5>(this (T1, T2, T3, T4, T5) value) { return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5); } public static Tuple<T1, T2, T3, T4, T5, T6> ToTuple<T1, T2, T3, T4, T5, T6>(this (T1, T2, T3, T4, T5, T6) value) { return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6); } public static Tuple<T1, T2, T3, T4, T5, T6, T7> ToTuple<T1, T2, T3, T4, T5, T6, T7>(this (T1, T2, T3, T4, T5, T6, T7) value) { return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8>(this (T1, T2, T3, T4, T5, T6, T7, T8) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1))); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2))); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3))); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4))); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5))); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6))); } public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) value) { return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7))); } private static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct { return new ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest); } private static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLongRef<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { return new Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest); } } internal interface ITupleInternal { int Size { get; } int GetHashCode(IEqualityComparer comparer); string ToStringEnd(); } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct ValueTuple : IEquatable<ValueTuple>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple>, System.ITupleInternal { int System.ITupleInternal.Size => 0; public override bool Equals(object obj) { return obj is ValueTuple; } public bool Equals(ValueTuple other) { return true; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { return other is ValueTuple; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return 0; } public int CompareTo(ValueTuple other) { return 0; } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is ValueTuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return 0; } public override int GetHashCode() { return 0; } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return 0; } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return 0; } public override string ToString() { return "()"; } string System.ITupleInternal.ToStringEnd() { return ")"; } public static ValueTuple Create() { return default(ValueTuple); } public static ValueTuple<T1> Create<T1>(T1 item1) { return new ValueTuple<T1>(item1); } public static (T1, T2) Create<T1, T2>(T1 item1, T2 item2) { return (item1, item2); } public static (T1, T2, T3) Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) { return (item1, item2, item3); } public static (T1, T2, T3, T4) Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) { return (item1, item2, item3, item4); } public static (T1, T2, T3, T4, T5) Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { return (item1, item2, item3, item4, item5); } public static (T1, T2, T3, T4, T5, T6) Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { return (item1, item2, item3, item4, item5, item6); } public static (T1, T2, T3, T4, T5, T6, T7) Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { return (item1, item2, item3, item4, item5, item6, item7); } public static (T1, T2, T3, T4, T5, T6, T7, T8) Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { return new ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>(item1, item2, item3, item4, item5, item6, item7, Create(item8)); } internal static int CombineHashCodes(int h1, int h2) { return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2); } internal static int CombineHashCodes(int h1, int h2, int h3) { return HashHelpers.Combine(CombineHashCodes(h1, h2), h3); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8); } } public struct ValueTuple<T1> : IEquatable<ValueTuple<T1>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1>>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; public T1 Item1; int System.ITupleInternal.Size => 1; public ValueTuple(T1 item1) { Item1 = item1; } public override bool Equals(object obj) { if (obj is ValueTuple<T1>) { return Equals((ValueTuple<T1>)obj); } return false; } public bool Equals(ValueTuple<T1> other) { return s_t1Comparer.Equals(Item1, other.Item1); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple<T1> valueTuple)) { return false; } return comparer.Equals(Item1, valueTuple.Item1); } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1> valueTuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return Comparer<T1>.Default.Compare(Item1, valueTuple.Item1); } public int CompareTo(ValueTuple<T1> other) { return Comparer<T1>.Default.Compare(Item1, other.Item1); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is ValueTuple<T1> valueTuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return comparer.Compare(Item1, valueTuple.Item1); } public override int GetHashCode() { return s_t1Comparer.GetHashCode(Item1); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return comparer.GetHashCode(Item1); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return comparer.GetHashCode(Item1); } public override string ToString() { return "(" + Item1?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2> : IEquatable<(T1, T2)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2)>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; public T1 Item1; public T2 Item2; int System.ITupleInternal.Size => 2; public ValueTuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2>) { return Equals(((T1, T2))obj); } return false; } public bool Equals((T1, T2) other) { if (s_t1Comparer.Equals(Item1, other.Item1)) { return s_t2Comparer.Equals(Item2, other.Item2); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is (T1, T2) tuple)) { return false; } if (comparer.Equals(Item1, tuple.Item1)) { return comparer.Equals(Item2, tuple.Item2); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo(((T1, T2))other); } public int CompareTo((T1, T2) other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } return Comparer<T2>.Default.Compare(Item2, other.Item2); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is (T1, T2) tuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, tuple.Item1); if (num != 0) { return num; } return comparer.Compare(Item2, tuple.Item2); } public override int GetHashCode() { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2)); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2)); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2, T3> : IEquatable<(T1, T2, T3)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3)>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default; public T1 Item1; public T2 Item2; public T3 Item3; int System.ITupleInternal.Size => 3; public ValueTuple(T1 item1, T2 item2, T3 item3) { Item1 = item1; Item2 = item2; Item3 = item3; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2, T3>) { return Equals(((T1, T2, T3))obj); } return false; } public bool Equals((T1, T2, T3) other) { if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2)) { return s_t3Comparer.Equals(Item3, other.Item3); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is (T1, T2, T3) tuple)) { return false; } if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2)) { return comparer.Equals(Item3, tuple.Item3); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo(((T1, T2, T3))other); } public int CompareTo((T1, T2, T3) other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } num = Comparer<T2>.Default.Compare(Item2, other.Item2); if (num != 0) { return num; } return Comparer<T3>.Default.Compare(Item3, other.Item3); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is (T1, T2, T3) tuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, tuple.Item1); if (num != 0) { return num; } num = comparer.Compare(Item2, tuple.Item2); if (num != 0) { return num; } return comparer.Compare(Item3, tuple.Item3); } public override int GetHashCode() { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3)); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3)); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2, T3, T4> : IEquatable<(T1, T2, T3, T4)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4)>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default; private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default; public T1 Item1; public T2 Item2; public T3 Item3; public T4 Item4; int System.ITupleInternal.Size => 4; public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2, T3, T4>) { return Equals(((T1, T2, T3, T4))obj); } return false; } public bool Equals((T1, T2, T3, T4) other) { if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3)) { return s_t4Comparer.Equals(Item4, other.Item4); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is (T1, T2, T3, T4) tuple)) { return false; } if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3)) { return comparer.Equals(Item4, tuple.Item4); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3, T4>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo(((T1, T2, T3, T4))other); } public int CompareTo((T1, T2, T3, T4) other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } num = Comparer<T2>.Default.Compare(Item2, other.Item2); if (num != 0) { return num; } num = Comparer<T3>.Default.Compare(Item3, other.Item3); if (num != 0) { return num; } return Comparer<T4>.Default.Compare(Item4, other.Item4); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is (T1, T2, T3, T4) tuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, tuple.Item1); if (num != 0) { return num; } num = comparer.Compare(Item2, tuple.Item2); if (num != 0) { return num; } num = comparer.Compare(Item3, tuple.Item3); if (num != 0) { return num; } return comparer.Compare(Item4, tuple.Item4); } public override int GetHashCode() { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4)); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4)); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2, T3, T4, T5> : IEquatable<(T1, T2, T3, T4, T5)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4, T5)>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default; private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default; private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default; public T1 Item1; public T2 Item2; public T3 Item3; public T4 Item4; public T5 Item5; int System.ITupleInternal.Size => 5; public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2, T3, T4, T5>) { return Equals(((T1, T2, T3, T4, T5))obj); } return false; } public bool Equals((T1, T2, T3, T4, T5) other) { if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4)) { return s_t5Comparer.Equals(Item5, other.Item5); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is (T1, T2, T3, T4, T5) tuple)) { return false; } if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3) && comparer.Equals(Item4, tuple.Item4)) { return comparer.Equals(Item5, tuple.Item5); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3, T4, T5>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo(((T1, T2, T3, T4, T5))other); } public int CompareTo((T1, T2, T3, T4, T5) other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } num = Comparer<T2>.Default.Compare(Item2, other.Item2); if (num != 0) { return num; } num = Comparer<T3>.Default.Compare(Item3, other.Item3); if (num != 0) { return num; } num = Comparer<T4>.Default.Compare(Item4, other.Item4); if (num != 0) { return num; } return Comparer<T5>.Default.Compare(Item5, other.Item5); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is (T1, T2, T3, T4, T5) tuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, tuple.Item1); if (num != 0) { return num; } num = comparer.Compare(Item2, tuple.Item2); if (num != 0) { return num; } num = comparer.Compare(Item3, tuple.Item3); if (num != 0) { return num; } num = comparer.Compare(Item4, tuple.Item4); if (num != 0) { return num; } return comparer.Compare(Item5, tuple.Item5); } public override int GetHashCode() { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5)); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5)); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2, T3, T4, T5, T6> : IEquatable<(T1, T2, T3, T4, T5, T6)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6)>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default; private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default; private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default; private static readonly EqualityComparer<T6> s_t6Comparer = EqualityComparer<T6>.Default; public T1 Item1; public T2 Item2; public T3 Item3; public T4 Item4; public T5 Item5; public T6 Item6; int System.ITupleInternal.Size => 6; public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; Item6 = item6; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2, T3, T4, T5, T6>) { return Equals(((T1, T2, T3, T4, T5, T6))obj); } return false; } public bool Equals((T1, T2, T3, T4, T5, T6) other) { if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4) && s_t5Comparer.Equals(Item5, other.Item5)) { return s_t6Comparer.Equals(Item6, other.Item6); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is (T1, T2, T3, T4, T5, T6) tuple)) { return false; } if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3) && comparer.Equals(Item4, tuple.Item4) && comparer.Equals(Item5, tuple.Item5)) { return comparer.Equals(Item6, tuple.Item6); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo(((T1, T2, T3, T4, T5, T6))other); } public int CompareTo((T1, T2, T3, T4, T5, T6) other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } num = Comparer<T2>.Default.Compare(Item2, other.Item2); if (num != 0) { return num; } num = Comparer<T3>.Default.Compare(Item3, other.Item3); if (num != 0) { return num; } num = Comparer<T4>.Default.Compare(Item4, other.Item4); if (num != 0) { return num; } num = Comparer<T5>.Default.Compare(Item5, other.Item5); if (num != 0) { return num; } return Comparer<T6>.Default.Compare(Item6, other.Item6); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is (T1, T2, T3, T4, T5, T6) tuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, tuple.Item1); if (num != 0) { return num; } num = comparer.Compare(Item2, tuple.Item2); if (num != 0) { return num; } num = comparer.Compare(Item3, tuple.Item3); if (num != 0) { return num; } num = comparer.Compare(Item4, tuple.Item4); if (num != 0) { return num; } num = comparer.Compare(Item5, tuple.Item5); if (num != 0) { return num; } return comparer.Compare(Item6, tuple.Item6); } public override int GetHashCode() { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6)); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6)); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7> : IEquatable<(T1, T2, T3, T4, T5, T6, T7)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6, T7)>, System.ITupleInternal { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default; private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default; private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default; private static readonly EqualityComparer<T6> s_t6Comparer = EqualityComparer<T6>.Default; private static readonly EqualityComparer<T7> s_t7Comparer = EqualityComparer<T7>.Default; public T1 Item1; public T2 Item2; public T3 Item3; public T4 Item4; public T5 Item5; public T6 Item6; public T7 Item7; int System.ITupleInternal.Size => 7; public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; Item6 = item6; Item7 = item7; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7>) { return Equals(((T1, T2, T3, T4, T5, T6, T7))obj); } return false; } public bool Equals((T1, T2, T3, T4, T5, T6, T7) other) { if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4) && s_t5Comparer.Equals(Item5, other.Item5) && s_t6Comparer.Equals(Item6, other.Item6)) { return s_t7Comparer.Equals(Item7, other.Item7); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is (T1, T2, T3, T4, T5, T6, T7) tuple)) { return false; } if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3) && comparer.Equals(Item4, tuple.Item4) && comparer.Equals(Item5, tuple.Item5) && comparer.Equals(Item6, tuple.Item6)) { return comparer.Equals(Item7, tuple.Item7); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo(((T1, T2, T3, T4, T5, T6, T7))other); } public int CompareTo((T1, T2, T3, T4, T5, T6, T7) other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } num = Comparer<T2>.Default.Compare(Item2, other.Item2); if (num != 0) { return num; } num = Comparer<T3>.Default.Compare(Item3, other.Item3); if (num != 0) { return num; } num = Comparer<T4>.Default.Compare(Item4, other.Item4); if (num != 0) { return num; } num = Comparer<T5>.Default.Compare(Item5, other.Item5); if (num != 0) { return num; } num = Comparer<T6>.Default.Compare(Item6, other.Item6); if (num != 0) { return num; } return Comparer<T7>.Default.Compare(Item7, other.Item7); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is (T1, T2, T3, T4, T5, T6, T7) tuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, tuple.Item1); if (num != 0) { return num; } num = comparer.Compare(Item2, tuple.Item2); if (num != 0) { return num; } num = comparer.Compare(Item3, tuple.Item3); if (num != 0) { return num; } num = comparer.Compare(Item4, tuple.Item4); if (num != 0) { return num; } num = comparer.Compare(Item5, tuple.Item5); if (num != 0) { return num; } num = comparer.Compare(Item6, tuple.Item6); if (num != 0) { return num; } return comparer.Compare(Item7, tuple.Item7); } public override int GetHashCode() { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7)); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7)); } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; } string System.ITupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; } } [StructLayout(LayoutKind.Auto)] public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, System.ITupleInternal where TRest : struct { private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default; private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default; private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default; private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default; private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default; private static readonly EqualityComparer<T6> s_t6Comparer = EqualityComparer<T6>.Default; private static readonly EqualityComparer<T7> s_t7Comparer = EqualityComparer<T7>.Default; private static readonly EqualityComparer<TRest> s_tRestComparer = EqualityComparer<TRest>.Default; public T1 Item1; public T2 Item2; public T3 Item3; public T4 Item4; public T5 Item5; public T6 Item6; public T7 Item7; public TRest Rest; int System.ITupleInternal.Size { get { if ((object)Rest is System.ITupleInternal tupleInternal) { return 7 + tupleInternal.Size; } return 8; } } public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { if (!(rest is System.ITupleInternal)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleLastArgumentNotAValueTuple); } Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; Item6 = item6; Item7 = item7; Rest = rest; } public override bool Equals(object obj) { if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>) { return Equals((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)obj); } return false; } public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other) { if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4) && s_t5Comparer.Equals(Item5, other.Item5) && s_t6Comparer.Equals(Item6, other.Item6) && s_t7Comparer.Equals(Item7, other.Item7)) { return s_tRestComparer.Equals(Rest, other.Rest); } return false; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> valueTuple)) { return false; } if (comparer.Equals(Item1, valueTuple.Item1) && comparer.Equals(Item2, valueTuple.Item2) && comparer.Equals(Item3, valueTuple.Item3) && comparer.Equals(Item4, valueTuple.Item4) && comparer.Equals(Item5, valueTuple.Item5) && comparer.Equals(Item6, valueTuple.Item6) && comparer.Equals(Item7, valueTuple.Item7)) { return comparer.Equals(Rest, valueTuple.Rest); } return false; } int IComparable.CompareTo(object other) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other); } public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other) { int num = Comparer<T1>.Default.Compare(Item1, other.Item1); if (num != 0) { return num; } num = Comparer<T2>.Default.Compare(Item2, other.Item2); if (num != 0) { return num; } num = Comparer<T3>.Default.Compare(Item3, other.Item3); if (num != 0) { return num; } num = Comparer<T4>.Default.Compare(Item4, other.Item4); if (num != 0) { return num; } num = Comparer<T5>.Default.Compare(Item5, other.Item5); if (num != 0) { return num; } num = Comparer<T6>.Default.Compare(Item6, other.Item6); if (num != 0) { return num; } num = Comparer<T7>.Default.Compare(Item7, other.Item7); if (num != 0) { return num; } return Comparer<TRest>.Default.Compare(Rest, other.Rest); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> valueTuple)) { throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other"); } int num = comparer.Compare(Item1, valueTuple.Item1); if (num != 0) { return num; } num = comparer.Compare(Item2, valueTuple.Item2); if (num != 0) { return num; } num = comparer.Compare(Item3, valueTuple.Item3); if (num != 0) { return num; } num = comparer.Compare(Item4, valueTuple.Item4); if (num != 0) { return num; } num = comparer.Compare(Item5, valueTuple.Item5); if (num != 0) { return num; } num = comparer.Compare(Item6, valueTuple.Item6); if (num != 0) { return num; } num = comparer.Compare(Item7, valueTuple.Item7); if (num != 0) { return num; } return comparer.Compare(Rest, valueTuple.Rest); } public override int GetHashCode() { if (!((object)Rest is System.ITupleInternal tupleInternal)) { return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7)); } int size = tupleInternal.Size; if (size >= 8) { return tupleInternal.GetHashCode(); } switch (8 - size) { case 1: return ValueTuple.CombineHashCodes(s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); case 2: return ValueTuple.CombineHashCodes(s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); case 3: return ValueTuple.CombineHashCodes(s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); case 4: return ValueTuple.CombineHashCodes(s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); case 5: return ValueTuple.CombineHashCodes(s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); case 6: return ValueTuple.CombineHashCodes(s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); case 7: case 8: return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode()); default: return -1; } } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { if (!((object)Rest is System.ITupleInternal tupleInternal)) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7)); } int size = tupleInternal.Size; if (size >= 8) { return tupleInternal.GetHashCode(comparer); } switch (8 - size) { case 1: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); case 2: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); case 3: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); case 4: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); case 5: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); case 6: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); case 7: case 8: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer)); default: return -1; } } int System.ITupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } public override string ToString() { string[] obj; T1 val; object obj2; if (!((object)Rest is System.ITupleInternal tupleInternal)) { obj = new string[17] { "(", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; ref T1 reference = ref Item1; val = default(T1); if (val == null) { val = reference; reference = ref val; if (val == null) { obj2 = null; goto IL_005d; } } obj2 = reference.ToString(); goto IL_005d; } string[] obj3 = new string[16] { "(", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; ref T1 reference2 = ref Item1; val = default(T1); object obj4; if (val == null) { val = reference2; reference2 = ref val; if (val == null) { obj4 = null; goto IL_0262; } } obj4 = reference2.ToString(); goto IL_0262; IL_02e2: object obj5; obj3[5] = (string)obj5; obj3[6] = ", "; ref T4 reference3 = ref Item4; T4 val2 = default(T4); object obj6; if (val2 == null) { val2 = reference3; reference3 = ref val2; if (val2 == null) { obj6 = null; goto IL_0325; } } obj6 = reference3.ToString(); goto IL_0325; IL_03f3: object obj7; obj3[13] = (string)obj7; obj3[14] = ", "; obj3[15] = tupleInternal.ToStringEnd(); return string.Concat(obj3); IL_03ae: object obj8; obj3[11] = (string)obj8; obj3[12] = ", "; ref T7 reference4 = ref Item7; T7 val3 = default(T7); if (val3 == null) { val3 = reference4; reference4 = ref val3; if (val3 == null) { obj7 = null; goto IL_03f3; } } obj7 = reference4.ToString(); goto IL_03f3; IL_0120: object obj9; obj[7] = (string)obj9; obj[8] = ", "; ref T5 reference5 = ref Item5; T5 val4 = default(T5); object obj10; if (val4 == null) { val4 = reference5; reference5 = ref val4; if (val4 == null) { obj10 = null; goto IL_0164; } } obj10 = reference5.ToString(); goto IL_0164; IL_005d: obj[1] = (string)obj2; obj[2] = ", "; ref T2 reference6 = ref Item2; T2 val5 = default(T2); object obj11; if (val5 == null) { val5 = reference6; reference6 = ref val5; if (val5 == null) { obj11 = null; goto IL_009d; } } obj11 = reference6.ToString(); goto IL_009d; IL_0164: obj[9] = (string)obj10; obj[10] = ", "; ref T6 reference7 = ref Item6; T6 val6 = default(T6); object obj12; if (val6 == null) { val6 = reference7; reference7 = ref val6; if (val6 == null) { obj12 = null; goto IL_01a9; } } obj12 = reference7.ToString(); goto IL_01a9; IL_02a2: object obj13; obj3[3] = (string)obj13; obj3[4] = ", "; ref T3 reference8 = ref Item3; T3 val7 = default(T3); if (val7 == null) { val7 = reference8; reference8 = ref val7; if (val7 == null) { obj5 = null; goto IL_02e2; } } obj5 = reference8.ToString(); goto IL_02e2; IL_01ee: object obj14; obj[13] = (string)obj14; obj[14] = ", "; obj[15] = Rest.ToString(); obj[16] = ")"; return string.Concat(obj); IL_009d: obj[3] = (string)obj11; obj[4] = ", "; ref T3 reference9 = ref Item3; val7 = default(T3); object obj15; if (val7 == null) { val7 = reference9; reference9 = ref val7; if (val7 == null) { obj15 = null; goto IL_00dd; } } obj15 = reference9.ToString(); goto IL_00dd; IL_0325: obj3[7] = (string)obj6; obj3[8] = ", "; ref T5 reference10 = ref Item5; val4 = default(T5); object obj16; if (val4 == null) { val4 = reference10; reference10 = ref val4; if (val4 == null) { obj16 = null; goto IL_0369; } } obj16 = reference10.ToString(); goto IL_0369; IL_01a9: obj[11] = (string)obj12; obj[12] = ", "; ref T7 reference11 = ref Item7; val3 = default(T7); if (val3 == null) { val3 = reference11; reference11 = ref val3; if (val3 == null) { obj14 = null; goto IL_01ee; } } obj14 = reference11.ToString(); goto IL_01ee; IL_0262: obj3[1] = (string)obj4; obj3[2] = ", "; ref T2 reference12 = ref Item2; val5 = default(T2); if (val5 == null) { val5 = reference12; reference12 = ref val5; if (val5 == null) { obj13 = null; goto IL_02a2; } } obj13 = reference12.ToString(); goto IL_02a2; IL_00dd: obj[5] = (string)obj15; obj[6] = ", "; ref T4 reference13 = ref Item4; val2 = default(T4); if (val2 == null) { val2 = reference13; reference13 = ref val2; if (val2 == null) { obj9 = null; goto IL_0120; } } obj9 = reference13.ToString(); goto IL_0120; IL_0369: obj3[9] = (string)obj16; obj3[10] = ", "; ref T6 reference14 = ref Item6; val6 = default(T6); if (val6 == null) { val6 = reference14; reference14 = ref val6; if (val6 == null) { obj8 = null; goto IL_03ae; } } obj8 = reference14.ToString(); goto IL_03ae; } string System.ITupleInternal.ToStringEnd() { string[] array; T1 val; object obj; if (!((object)Rest is System.ITupleInternal tupleInternal)) { array = new string[16]; ref T1 reference = ref Item1; val = default(T1); if (val == null) { val = reference; reference = ref val; if (val == null) { obj = null; goto IL_0055; } } obj = reference.ToString(); goto IL_0055; } string[] array2 = new string[15]; ref T1 reference2 = ref Item1; val = default(T1); object obj2; if (val == null) { val = reference2; reference2 = ref val; if (val == null) { obj2 = null; goto IL_0251; } } obj2 = reference2.ToString(); goto IL_0251; IL_02d1: object obj3; array2[4] = (string)obj3; array2[5] = ", "; ref T4 reference3 = ref Item4; T4 val2 = default(T4); object obj4; if (val2 == null) { val2 = reference3; reference3 = ref val2; if (val2 == null) { obj4 = null; goto IL_0314; } } obj4 = reference3.ToString(); goto IL_0314; IL_03e1: object obj5; array2[12] = (string)obj5; array2[13] = ", "; array2[14] = tupleInternal.ToStringEnd(); return string.Concat(array2); IL_039c: object obj6; array2[10] = (string)obj6; array2[11] = ", "; ref T7 reference4 = ref Item7; T7 val3 = default(T7); if (val3 == null) { val3 = reference4; reference4 = ref val3; if (val3 == null) { obj5 = null; goto IL_03e1; } } obj5 = reference4.ToString(); goto IL_03e1; IL_0118: object obj7; array[6] = (string)obj7; array[7] = ", "; ref T5 reference5 = ref Item5; T5 val4 = default(T5); object obj8; if (val4 == null) { val4 = reference5; reference5 = ref val4; if (val4 == null) { obj8 = null; goto IL_015b; } } obj8 = reference5.ToString(); goto IL_015b; IL_0055: array[0] = (string)obj; array[1] = ", "; ref T2 reference6 = ref Item2; T2 val5 = default(T2); object obj9; if (val5 == null) { val5 = reference6; reference6 = ref val5; if (val5 == null) { obj9 = null; goto IL_0095; } } obj9 = reference6.ToString(); goto IL_0095; IL_015b: array[8] = (string)obj8; array[9] = ", "; ref T6 reference7 = ref Item6; T6 val6 = default(T6); object obj10; if (val6 == null) { val6 = reference7; reference7 = ref val6; if (val6 == null) { obj10 = null; goto IL_01a0; } } obj10 = reference7.ToString(); goto IL_01a0; IL_0291: object obj11; array2[2] = (string)obj11; array2[3] = ", "; ref T3 reference8 = ref Item3; T3 val7 = default(T3); if (val7 == null) { val7 = reference8; reference8 = ref val7; if (val7 == null) { obj3 = null; goto IL_02d1; } } obj3 = reference8.ToString(); goto IL_02d1; IL_01e5: object obj12; array[12] = (string)obj12; array[13] = ", "; array[14] = Rest.ToString(); array[15] = ")"; return string.Concat(array); IL_0095: array[2] = (string)obj9; array[3] = ", "; ref T3 reference9 = ref Item3; val7 = default(T3); object obj13; if (val7 == null) { val7 = reference9; reference9 = ref val7; if (val7 == null) { obj13 = null; goto IL_00d5; } } obj13 = reference9.ToString(); goto IL_00d5; IL_0314: array2[6] = (string)obj4; array2[7] = ", "; ref T5 reference10 = ref Item5; val4 = default(T5); object obj14; if (val4 == null) { val4 = reference10; reference10 = ref val4; if (val4 == null) { obj14 = null; goto IL_0357; } } obj14 = reference10.ToString(); goto IL_0357; IL_01a0: array[10] = (string)obj10; array[11] = ", "; ref T7 reference11 = ref Item7; val3 = default(T7); if (val3 == null) { val3 = reference11; reference11 = ref val3; if (val3 == null) { obj12 = null; goto IL_01e5; } } obj12 = reference11.ToString(); goto IL_01e5; IL_0251: array2[0] = (string)obj2; array2[1] = ", "; ref T2 reference12 = ref Item2; val5 = default(T2); if (val5 == null) { val5 = reference12; reference12 = ref val5; if (val5 == null) { obj11 = null; goto IL_0291; } } obj11 = reference12.ToString(); goto IL_0291; IL_00d5: array[4] = (string)obj13; array[5] = ", "; ref T4 reference13 = ref Item4; val2 = default(T4); if (val2 == null) { val2 = reference13; reference13 = ref val2; if (val2 == null) { obj7 = null; goto IL_0118; } } obj7 = reference13.ToString(); goto IL_0118; IL_0357: array2[8] = (string)obj14; array2[9] = ", "; ref T6 reference14 = ref Item6; val6 = default(T6); if (val6 == null) { val6 = reference14; reference14 = ref val6; if (val6 == null) { obj6 = null; goto IL_039c; } } obj6 = reference14.ToString(); goto IL_039c; } } internal static class SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR))); internal static string ArgumentException_ValueTupleIncorrectType => GetResourceString("ArgumentException_ValueTupleIncorrectType"); internal static string ArgumentException_ValueTupleLastArgumentNotAValueTuple => GetResourceString("ArgumentException_ValueTupleLastArgumentNotAValueTuple"); private static bool UsingResourceKeys() { return s_usingResourceKeys; } internal static string GetResourceString(string resourceKey) { if (UsingResourceKeys()) { return resourceKey; } string result = null; try { result = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } return result; } internal static string GetResourceString(string resourceKey, string defaultString) { string resourceString = GetResourceString(resourceKey); if (!(resourceKey == resourceString) && resourceString != null) { return resourceString; } return defaultString; } internal static string Format(string resourceFormat, object? p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object? p1, object? p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object? p1, object? p2, object? p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } internal static string Format(string resourceFormat, params object?[]? args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(provider, resourceFormat, p1); } internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(provider, resourceFormat, p1, p2); } internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(provider, resourceFormat, p1, p2, p3); } internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(provider, resourceFormat, args); } return resourceFormat; } } } namespace System.Numerics.Hashing { internal static class HashHelpers { public static readonly int RandomSeed = Guid.NewGuid().GetHashCode(); public static int Combine(int h1, int h2) { uint num = (uint)(h1 << 5) | ((uint)h1 >> 27); return ((int)num + h1) ^ h2; } } } namespace System.Runtime.CompilerServices { [CLSCompliant(false)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue)] public sealed class TupleElementNamesAttribute : Attribute { private readonly string[] _transformNames; public IList<string> TransformNames => _transformNames; public TupleElementNamesAttribute(string[] transformNames) { if (transformNames == null) { throw new ArgumentNullException("transformNames"); } _transformNames = transformNames; } } }
YoutubeDLSharp.dll
Decompiled 2 weeks 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.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 YoutubeDLSharp.Converters; using YoutubeDLSharp.Helpers; using YoutubeDLSharp.Metadata; using YoutubeDLSharp.Options; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyCompany("Bluegrams")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© 2020-2025 Bluegrams")] [assembly: AssemblyDescription("\r\n\t\tA simple .NET wrapper library for youtube-dl and yt-dlp.\r\n\r\nNote: Package versions >= 1.0 are optimized to work with yt-dlp.\r\nPackage versions 0.x retain support for the original youtube-dl.\r\n\t")] [assembly: AssemblyFileVersion("1.1.2.25113")] [assembly: AssemblyInformationalVersion("1.1.2+278031d4e0ac90b92bd8b5860e5bf26e777afe14")] [assembly: AssemblyProduct("YoutubeDLSharp")] [assembly: AssemblyTitle("YoutubeDLSharp")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Bluegrams/YoutubeDLSharp")] [assembly: AssemblyVersion("1.1.2.25113")] namespace YoutubeDLSharp { public enum DownloadState { None, PreProcessing, Downloading, PostProcessing, Error, Success } public class DownloadProgress { public DownloadState State { get; } public float Progress { get; } public string TotalDownloadSize { get; } public string DownloadSpeed { get; } public string ETA { get; } public int VideoIndex { get; } public string Data { get; } public DownloadProgress(DownloadState status, float progress = 0f, string totalDownloadSize = null, string downloadSpeed = null, string eta = null, int index = 1, string data = null) { State = status; Progress = progress; TotalDownloadSize = totalDownloadSize; DownloadSpeed = downloadSpeed; ETA = eta; VideoIndex = index; Data = data; } } public class RunResult<T> { public bool Success { get; } public string[] ErrorOutput { get; } public T Data { get; } public RunResult(bool success, string[] error, T result) { Success = success; ErrorOutput = error; Data = result; } } public static class Utils { internal class FFmpegApi { public class Root { [JsonProperty("version")] public string Version { get; set; } [JsonProperty("permalink")] public string Permalink { get; set; } [JsonProperty("bin")] public Bin Bin { get; set; } } public class Bin { [JsonProperty("windows-64")] public OsBinVersion Windows64 { get; set; } [JsonProperty("linux-64")] public OsBinVersion Linux64 { get; set; } [JsonProperty("osx-64")] public OsBinVersion Osx64 { get; set; } } public class OsBinVersion { [JsonProperty("ffmpeg")] public string Ffmpeg { get; set; } [JsonProperty("ffprobe")] public string Ffprobe { get; set; } } public enum BinaryType { [EnumMember(Value = "ffmpeg")] FFmpeg, [EnumMember(Value = "ffprobe")] FFprobe } } private static readonly 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(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() { return OSHelper.GetOSVersion() switch { OSVersion.Windows => "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe", OSVersion.OSX => "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos", OSVersion.Linux => "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp", _ => throw new Exception("Your OS isn't supported"), }; } private static string GetYtDlpBinaryName() { return Path.GetFileName(GetYtDlpDownloadUrl()); } 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 directoryPath = "") { string ytDlpDownloadUrl = GetYtDlpDownloadUrl(); if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } string downloadLocation = Path.Combine(directoryPath, Path.GetFileName(ytDlpDownloadUrl)); File.WriteAllBytes(downloadLocation, await DownloadFileBytesAsync(ytDlpDownloadUrl)); } public static async Task DownloadFFmpeg(string directoryPath = "") { await FFDownloader(directoryPath); } public static async Task DownloadFFprobe(string directoryPath = "") { await FFDownloader(directoryPath, FFmpegApi.BinaryType.FFprobe); } private static async Task FFDownloader(string directoryPath = "", FFmpegApi.BinaryType binary = FFmpegApi.BinaryType.FFmpeg) { if (string.IsNullOrEmpty(directoryPath)) { directoryPath = Directory.GetCurrentDirectory(); } FFmpegApi.Root root = JsonConvert.DeserializeObject<FFmpegApi.Root>(await (await _client.GetAsync("https://ffbinaries.com/api/v1/version/latest")).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); } } private 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), Print = "after_move:outfile: %(filepath)s" }; } private YoutubeDLProcess CreateYoutubeDLProcess() { return new YoutubeDLProcess(YoutubeDLPath) { PythonPath = PythonInterpreterPath }; } } public class YoutubeDLProcess { private static readonly Regex rgxPlaylist = new Regex("Downloading video (\\d+) of (\\d+)", RegexOptions.Compiled); private static readonly Regex rgxProgress = new Regex("\\[download\\]\\s+(?:(?<percent>[\\d\\.]+)%(?:\\s+of\\s+\\~?\\s*(?<total>[\\d\\.\\w]+))?\\s+at\\s+(?:(?<speed>[\\d\\.\\w]+\\/s)|[\\w\\s]+)\\s+ETA\\s(?<eta>[\\d\\:]+))?", RegexOptions.Compiled); private static readonly Regex rgxPost = new Regex("\\[(\\w+)\\]\\s+", RegexOptions.Compiled); public string PythonPath { get; set; } public string ExecutablePath { get; set; } public event EventHandler<DataReceivedEventArgs> OutputReceived; public event EventHandler<DataReceivedEventArgs> ErrorReceived; public YoutubeDLProcess(string executablePath = "yt-dlp.exe") { ExecutablePath = executablePath; } internal string ConvertToArgs(string[] urls, OptionSet options) { return options.ToString() + " -- " + ((urls != null) ? string.Join(" ", urls.Select((string s) => "\"" + s + "\"")) : string.Empty); } internal void RedirectToError(DataReceivedEventArgs e) { this.ErrorReceived?.Invoke(this, e); } public async Task<int> RunAsync(string[] urls, OptionSet options) { return await RunAsync(urls, options, CancellationToken.None); } public async Task<int> RunAsync(string[] urls, OptionSet options, CancellationToken ct, IProgress<DownloadProgress> progress = null) { TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); Process process = new Process(); ProcessStartInfo processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8 }; if (!string.IsNullOrEmpty(PythonPath)) { processStartInfo.FileName = PythonPath; processStartInfo.Arguments = "\"" + ExecutablePath + "\" " + ConvertToArgs(urls, options); } else { processStartInfo.FileName = ExecutablePath; processStartInfo.Arguments = ConvertToArgs(urls, options); } process.EnableRaisingEvents = true; process.StartInfo = processStartInfo; TaskCompletionSource<bool> tcsOut = new TaskCompletionSource<bool>(); bool isDownloading = false; process.OutputDataReceived += delegate(object o, DataReceivedEventArgs e) { if (e.Data == null) { tcsOut.SetResult(result: true); } else { Match match; if ((match = rgxProgress.Match(e.Data)).Success) { if (match.Groups.Count > 1 && match.Groups[1].Length > 0) { float progress2 = float.Parse(match.Groups[1].ToString(), CultureInfo.InvariantCulture) / 100f; Group group = match.Groups["total"]; string totalDownloadSize = (group.Success ? group.Value : null); Group group2 = match.Groups["speed"]; string downloadSpeed = (group2.Success ? group2.Value : null); Group group3 = match.Groups["eta"]; string eta = (group3.Success ? group3.Value : null); progress?.Report(new DownloadProgress(DownloadState.Downloading, progress2, totalDownloadSize, downloadSpeed, eta)); } else { progress?.Report(new DownloadProgress(DownloadState.Downloading)); } isDownloading = true; } else if ((match = rgxPlaylist.Match(e.Data)).Success) { int index = int.Parse(match.Groups[1].Value); progress?.Report(new DownloadProgress(DownloadState.PreProcessing, 0f, null, null, null, index)); isDownloading = false; } else if (isDownloading && (match = rgxPost.Match(e.Data)).Success) { progress?.Report(new DownloadProgress(DownloadState.PostProcessing, 1f)); isDownloading = false; } this.OutputReceived?.Invoke(this, e); } }; TaskCompletionSource<bool> tcsError = new TaskCompletionSource<bool>(); process.ErrorDataReceived += delegate(object o, DataReceivedEventArgs e) { if (e.Data == null) { tcsError.SetResult(result: true); } else { progress?.Report(new DownloadProgress(DownloadState.Error, 0f, null, null, null, 1, e.Data)); this.ErrorReceived?.Invoke(this, e); } }; process.Exited += async delegate { await tcsOut.Task; await tcsError.Task; tcs.TrySetResult(process.ExitCode); process.Dispose(); }; ct.Register(delegate { if (!tcs.Task.IsCompleted) { tcs.TrySetCanceled(); } try { if (!process.HasExited) { process.KillTree(); } } catch { } }); if (!(await Task.Run(() => process.Start()))) { tcs.TrySetException(new InvalidOperationException("Failed to start yt-dlp process.")); } process.BeginOutputReadLine(); process.BeginErrorReadLine(); progress?.Report(new DownloadProgress(DownloadState.PreProcessing)); return await tcs.Task; } } } namespace YoutubeDLSharp.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 MultiOption<string> pluginDirs = new MultiOption<string>("--plugin-dirs"); private Option<bool> noPluginDirs = new Option<bool>("--no-plugin-dirs"); 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"); 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 MultiValue<string> PluginDirs { get { return pluginDirs.Value; } set { pluginDirs.Value = value; } } public bool NoPluginDirs { get { return noPluginDirs.Value; } set { noPluginDirs.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; CustomOptions = CustomOptions.Concat(new Option<T>[1] { option }).ToArray(); } public void SetCustomOption<T>(string optionString, T value) { foreach (IOption item in CustomOptions.Where((IOption o) => o.OptionStrings.Contains(optionString))) { if (item is Option<T> option) { option.Value = value; continue; } throw new ArgumentException($"Value passed to option '{optionString}' has invalid type '{value.GetType()}'."); } } public void DeleteCustomOption(string optionString) { CustomOptions = CustomOptions.Where((IOption o) => !o.OptionStrings.Contains(optionString)).ToArray(); } } internal static class Utils { internal static T OptionValueFromString<T>(string stringValue) { if (typeof(T) == typeof(bool)) { return (T)(object)true; } if (typeof(T) == typeof(Enum)) { string value = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(stringValue); return (T)Enum.Parse(typeof(T), value); } if (typeof(T) == typeof(DateTime)) { return (T)(object)DateTime.ParseExact(stringValue, "yyyyMMdd", null); } return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(stringValue); } internal static string OptionValueToString<T>(T value) { if (value is bool) { return string.Empty; } if (value is Enum) { return " \"" + value.ToString().ToLower() + "\""; } if (value is DateTime) { object obj = value; return " " + ((DateTime)((obj is DateTime) ? obj : null)).ToString("yyyyMMdd"); } if (value is string) { return $" \"{value}\""; } T val = value; return " " + val; } } } namespace YoutubeDLSharp.Metadata { public class ChapterData { [JsonProperty("start_time")] public float? StartTime { get; set; } [JsonProperty("end_time")] public float? EndTime { get; set; } [JsonProperty("title")] public string Title { get; set; } } public class CommentData { [JsonProperty("id")] public string ID { get; set; } [JsonProperty("author")] public string Author { get; set; } [JsonProperty("author_id")] public string AuthorID { get; set; } [JsonProperty("author_thumbnail")] public string AuthorThumbnail { get; set; } [JsonProperty("html")] public string Html { get; set; } [JsonProperty("text")] public string Text { get; set; } [JsonProperty("timestamp")] [JsonConverter(typeof(UnixTimestampConverter))] public DateTime Timestamp { get; set; } [JsonProperty("parent")] public string Parent { get; set; } [JsonProperty("like_count")] public int? LikeCount { get; set; } [JsonProperty("dislike_count")] public int? DislikeCount { get; set; } [JsonProperty("is_favorited")] public bool? IsFavorited { get; set; } [JsonProperty("author_is_uploader")] public bool? AuthorIsUploader { get; set; } } public class FormatData { [JsonProperty("url")] public string Url { get; set; } [JsonProperty("manifest_ur
YoutubeExplode.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
#define DEBUG using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; 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.Json; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Sources; using System.Xml.Linq; using AngleSharp.Dom; using AngleSharp.Html.Dom; using AngleSharp.Html.Parser; using Deorcify; using Microsoft.CodeAnalysis; using YoutubeExplode.Bridge; using YoutubeExplode.Bridge.Cipher; using YoutubeExplode.Channels; using YoutubeExplode.Common; using YoutubeExplode.Exceptions; using YoutubeExplode.Playlists; using YoutubeExplode.Search; using YoutubeExplode.Utils; using YoutubeExplode.Utils.Extensions; using YoutubeExplode.Videos; using YoutubeExplode.Videos.ClosedCaptions; using YoutubeExplode.Videos.Streams; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Tyrrrz")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("Copyright (C) Oleksii Holub")] [assembly: AssemblyDescription("Abstraction layer over YouTube's internal API. Note: this package has limited availability in Russia and Belarus.")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0-dev+0b5cc1ec2a1fbe885195ef344c15844ff386aeeb")] [assembly: AssemblyProduct("YoutubeExplode")] [assembly: AssemblyTitle("YoutubeExplode")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { Initializer.Execute(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } [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; } } } [ExcludeFromCodeCoverage] internal static class PolyfillExtensions { public static async Task<Stream> GetStreamAsync(this HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { try { HttpResponseMessage response = await httpClient.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); return await ReadAsStreamAsync(response.Content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (OperationCanceledException ex) when (ex.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); } } public static async Task<Stream> GetStreamAsync(this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { return await GetStreamAsync(httpClient, requestUri.ToString(), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<byte[]> GetByteArrayAsync(this HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { try { using HttpResponseMessage response = await httpClient.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); return await ReadAsByteArrayAsync(response.Content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (OperationCanceledException ex) when (ex.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); } } public static async Task<byte[]> GetByteArrayAsync(this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { return await GetByteArrayAsync(httpClient, requestUri.ToString(), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<string> GetStringAsync(this HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { try { using HttpResponseMessage response = await httpClient.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); return await ReadAsStringAsync(response.Content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (OperationCanceledException ex) when (ex.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); } } public static async Task<string> GetStringAsync(this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { return await GetStringAsync(httpClient, requestUri.ToString(), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<Stream> ReadAsStreamAsync(this HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await httpContent.ReadAsStreamAsync().ConfigureAwait(continueOnCapturedContext: false); } public static async Task<byte[]> ReadAsByteArrayAsync(this HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await httpContent.ReadAsByteArrayAsync().ConfigureAwait(continueOnCapturedContext: false); } public static async Task<string> ReadAsStringAsync(this HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await httpContent.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false); } public static async Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default(CancellationToken)) { TaskCompletionSource<object?> tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); try { process.EnableRaisingEvents = true; } catch when (process.HasExited) { return; } process.Exited += HandleExited; try { using (cancellationToken.Register(delegate { tcs.TrySetCanceled(cancellationToken); })) { await tcs.Task; } } finally { process.Exited -= HandleExited; } void HandleExited(object? sender, EventArgs args) { tcs.TrySetResult(null); } } public static bool IsAssignableTo(this Type type, Type? otherType) { return otherType?.IsAssignableFrom(type) ?? false; } public static string ReplaceLineEndings(this string str, string replacementText) { return Replace(Replace(Replace(str, "\r\n", "\n", StringComparison.Ordinal), "\r", "\n", StringComparison.Ordinal), "\n", replacementText, StringComparison.Ordinal); } public static string ReplaceLineEndings(this string str) { return ReplaceLineEndings(str, Environment.NewLine); } public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) { Task cancellationTask = Task.Delay(timeout, cancellationToken); Task finishedTask = await Task.WhenAny(new Task[2] { task, cancellationTask }).ConfigureAwait(continueOnCapturedContext: false); await finishedTask.ConfigureAwait(continueOnCapturedContext: false); if (finishedTask == cancellationTask) { throw new TimeoutException("The operation has timed out."); } } public static async Task WaitAsync(this Task task, CancellationToken cancellationToken) { await WaitAsync(task, Timeout.InfiniteTimeSpan, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task WaitAsync(this Task task, TimeSpan timeout) { await WaitAsync(task, timeout, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout, CancellationToken cancellationToken) { Task cancellationTask = Task.Delay(timeout, cancellationToken); Task finishedTask = await Task.WhenAny(new Task[2] { task, cancellationTask }).ConfigureAwait(continueOnCapturedContext: false); await finishedTask.ConfigureAwait(continueOnCapturedContext: false); if (finishedTask == cancellationTask) { throw new TimeoutException("The operation has timed out."); } return task.Result; } public static async Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken) { return await WaitAsync(task, Timeout.InfiniteTimeSpan, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout) { return await WaitAsync(task, timeout, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false); } public static int ReadAtLeast(this Stream stream, byte[] buffer, int minimumBytes, bool throwOnEndOfStream = true) { int i; int num; for (i = 0; i < buffer.Length; i += num) { num = stream.Read(buffer, i, Math.Min(minimumBytes, buffer.Length - i)); if (num <= 0) { break; } } if (i < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return i; } public static void ReadExactly(this Stream stream, byte[] buffer, int offset, int count) { int num; for (int i = 0; i < count; i += num) { num = stream.Read(buffer, offset + i, count - i); if (num <= 0) { throw new EndOfStreamException(); } } } public static void ReadExactly(this Stream stream, byte[] buffer) { stream.ReadExactly(buffer, 0, buffer.Length); } public static async Task<int> ReadAtLeastAsync(this Stream stream, byte[] buffer, int minimumBytes, bool throwOnEndOfStream = true, CancellationToken cancellationToken = default(CancellationToken)) { int totalBytesRead; int bytesRead; for (totalBytesRead = 0; totalBytesRead < buffer.Length; totalBytesRead += bytesRead) { bytesRead = await stream.ReadAsync(buffer, totalBytesRead, Math.Min(minimumBytes, buffer.Length - totalBytesRead), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (bytesRead <= 0) { break; } } if (totalBytesRead < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return totalBytesRead; } public static async Task ReadExactlyAsync(this Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken = default(CancellationToken)) { int bytesRead; for (int totalBytesRead = 0; totalBytesRead < count; totalBytesRead += bytesRead) { bytesRead = await stream.ReadAsync(buffer, offset + totalBytesRead, count - totalBytesRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (bytesRead <= 0) { throw new EndOfStreamException(); } } } public static async Task ReadExactlyAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { await stream.ReadExactlyAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static int ReadAtLeast(this Stream stream, Span<byte> buffer, int minimumBytes, bool throwOnEndOfStream = true) { int i; int num; for (i = 0; i < buffer.Length; i += num) { num = Read(stream, buffer.Slice(i)); if (num <= 0) { break; } } if (i < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return i; } public static void ReadExactly(this Stream stream, Span<byte> buffer) { byte[] array = buffer.ToArray(); stream.ReadExactly(array, 0, array.Length); array.CopyTo(buffer); } public static async Task<int> ReadAtLeastAsync(this Stream stream, Memory<byte> buffer, int minimumBytes, bool throwOnEndOfStream = true, CancellationToken cancellationToken = default(CancellationToken)) { int totalBytesRead; int bytesRead; for (totalBytesRead = 0; totalBytesRead < buffer.Length; totalBytesRead += bytesRead) { bytesRead = await ReadAsync(stream, buffer.Slice(totalBytesRead), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (bytesRead <= 0) { break; } } if (totalBytesRead < minimumBytes && throwOnEndOfStream) { throw new EndOfStreamException(); } return totalBytesRead; } public static async Task ReadExactlyAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken)) { byte[] bufferArray = buffer.ToArray(); await stream.ReadExactlyAsync(bufferArray, 0, bufferArray.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); bufferArray.CopyTo(buffer); } public static Task CancelAsync(this CancellationTokenSource cts) { cts.Cancel(); return Task.CompletedTask; } public static void Deconstruct(this DictionaryEntry entry, out object key, out object? value) { key = entry.Key; value = entry.Value; } public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value) { key = pair.Key; value = pair.Value; } public static IEnumerable<Match> AsEnumerable(this MatchCollection matchCollection) { return matchCollection.Cast<Match>(); } public static IEnumerator<Match> GetEnumerator(this MatchCollection matchCollection) { return matchCollection.AsEnumerable().GetEnumerator(); } public static Match[] ToArray(this MatchCollection matchCollection) { return matchCollection.AsEnumerable().ToArray(); } public static bool StartsWith(this string str, char c) { return str.Length > 0 && str[0] == c; } public static bool EndsWith(this string str, char c) { int result; if (str.Length > 0) { result = ((str[str.Length - 1] == c) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } public static bool Contains(this string str, char c) { return str.IndexOf(c) >= 0; } public static string Replace(this string str, string oldValue, string? newValue, StringComparison comparison) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; int num2 = 0; while (true) { num = str.IndexOf(oldValue, num, comparison); if (num < 0) { break; } stringBuilder.Append(str, num2, num - num2); stringBuilder.Append(newValue); num += oldValue.Length; num2 = num; } stringBuilder.Append(str, num2, str.Length - num2); return stringBuilder.ToString(); } public static string Replace(this string str, string oldValue, string? newValue, bool ignoreCase, CultureInfo? culture) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; int num2 = 0; while (true) { num = (culture ?? CultureInfo.CurrentCulture).CompareInfo.IndexOf(str, oldValue, num, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); if (num < 0) { break; } stringBuilder.Append(str, num2, num - num2); stringBuilder.Append(newValue); num += oldValue.Length; num2 = num; } stringBuilder.Append(str, num2, str.Length - num2); return stringBuilder.ToString(); } public static string[] Split(this string str, char separator, int count, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new char[1] { separator }, count, options); } public static string[] Split(this string str, char separator, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new char[1] { separator }, options); } public static string[] Split(this string str, string? separator, int count, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new string[1] { separator ?? "" }, count, options); } public static string[] Split(this string str, string? separator, StringSplitOptions options = StringSplitOptions.None) { return str.Split(new string[1] { separator ?? "" }, options); } public static void NextBytes(this Random random, Span<byte> buffer) { byte[] array = buffer.ToArray(); random.NextBytes(array); array.CopyTo(buffer); } public static int Read(this Stream stream, byte[] buffer) { return stream.Read(buffer, 0, buffer.Length); } public static void Write(this Stream stream, byte[] buffer) { stream.Write(buffer, 0, buffer.Length); } public static async Task CopyToAsync(this Stream stream, Stream destination, CancellationToken cancellationToken = default(CancellationToken)) { await stream.CopyToAsync(destination, 81920, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task<int> ReadAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { return await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static async Task WriteAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static int Read(this Stream stream, Span<byte> buffer) { byte[] array = buffer.ToArray(); int result = stream.Read(array, 0, array.Length); array.CopyTo(buffer); return result; } public static void Write(this Stream stream, ReadOnlySpan<byte> buffer) { byte[] array = buffer.ToArray(); stream.Write(array, 0, array.Length); } public static async Task<int> ReadAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken)) { byte[] bufferArray = buffer.ToArray(); int result = await stream.ReadAsync(bufferArray, 0, bufferArray.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); bufferArray.CopyTo(buffer); return result; } public static async Task WriteAsync(this Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken)) { byte[] bufferArray = buffer.ToArray(); await stream.WriteAsync(bufferArray, 0, bufferArray.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } public static int Read(this StreamReader reader, char[] buffer) { return reader.Read(buffer, 0, buffer.Length); } public static async Task<int> ReadAsync(this StreamReader reader, char[] buffer, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); return await reader.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(continueOnCapturedContext: false); } public static int Read(this StreamReader reader, Span<char> buffer) { char[] array = buffer.ToArray(); int result = reader.Read(array, 0, array.Length); array.CopyTo(buffer); return result; } public static async Task<int> ReadAsync(this StreamReader reader, Memory<char> buffer, CancellationToken cancellationToken = default(CancellationToken)) { char[] bufferArray = buffer.ToArray(); cancellationToken.ThrowIfCancellationRequested(); int result = await reader.ReadAsync(bufferArray, 0, bufferArray.Length).ConfigureAwait(continueOnCapturedContext: false); bufferArray.CopyTo(buffer); return result; } public static void Write(this StreamWriter writer, ReadOnlySpan<char> buffer) { char[] array = buffer.ToArray(); writer.Write(array, 0, array.Length); } public static async Task WriteAsync(this StreamWriter writer, Memory<char> buffer, CancellationToken cancellationToken = default(CancellationToken)) { char[] bufferArray = buffer.ToArray(); cancellationToken.ThrowIfCancellationRequested(); await writer.WriteAsync(bufferArray, 0, bufferArray.Length).ConfigureAwait(continueOnCapturedContext: false); } public static bool Contains(this string str, char c, StringComparison comparison) { return Contains(str, c.ToString(), comparison); } public static bool Contains(this string str, string sub, StringComparison comparison) { return str.IndexOf(sub, comparison) >= 0; } } namespace YoutubeExplode { public class YoutubeClient : IDisposable { private readonly HttpClient _youtubeHttp; public VideoClient Videos { get; } public PlaylistClient Playlists { get; } public ChannelClient Channels { get; } public SearchClient Search { get; } public YoutubeClient(HttpClient http, IReadOnlyList<Cookie> initialCookies) { _youtubeHttp = new HttpClient(new YoutubeHttpHandler(http, initialCookies), disposeHandler: true); Videos = new VideoClient(_youtubeHttp); Playlists = new PlaylistClient(_youtubeHttp); Channels = new ChannelClient(_youtubeHttp); Search = new SearchClient(_youtubeHttp); } public YoutubeClient(HttpClient http) : this(http, Array.Empty<Cookie>()) { } public YoutubeClient(IReadOnlyList<Cookie> initialCookies) : this(Http.Client, initialCookies) { } public YoutubeClient() : this(Http.Client) { } public void Dispose() { _youtubeHttp.Dispose(); } } internal class YoutubeHttpHandler : ClientDelegatingHandler { private readonly CookieContainer _cookieContainer = new CookieContainer(); public YoutubeHttpHandler(HttpClient http, IReadOnlyList<Cookie> initialCookies, bool disposeClient = false) : base(http, disposeClient) { _cookieContainer.Add(new Cookie("SOCS", "CAISEwgDEgk4MTM4MzYzNTIaAmVuIAEaBgiApPzGBg") { Domain = "youtube.com" }); foreach (Cookie initialCookie in initialCookies) { _cookieContainer.Add(initialCookie); } } private string? TryGenerateAuthHeaderValue(Uri uri) { Cookie[] source = _cookieContainer.GetCookies(uri).Cast<Cookie>().ToArray(); string text = source.FirstOrDefault((Cookie c) => string.Equals(c.Name, "__Secure-3PAPISID", StringComparison.Ordinal))?.Value ?? source.FirstOrDefault((Cookie c) => string.Equals(c.Name, "SAPISID", StringComparison.Ordinal))?.Value; if (string.IsNullOrWhiteSpace(text)) { return null; } long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); string domain = uri.GetDomain(); string s = $"{num} {text} {domain}"; string arg = Hash.Compute(SHA1.Create(), Encoding.UTF8.GetBytes(s)).ToHex(); return $"SAPISIDHASH {num}_{arg}"; } private HttpRequestMessage HandleRequest(HttpRequestMessage request) { if ((object)request.RequestUri == null) { return request; } if (request.RequestUri.AbsolutePath.StartsWith("/youtubei/", StringComparison.Ordinal) && !UrlEx.ContainsQueryParameter(request.RequestUri.Query, "key")) { request.RequestUri = new Uri(UrlEx.SetQueryParameter(request.RequestUri.OriginalString, "key", "AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w")); } if (!UrlEx.ContainsQueryParameter(request.RequestUri.Query, "hl")) { request.RequestUri = new Uri(UrlEx.SetQueryParameter(request.RequestUri.OriginalString, "hl", "en")); } if (!request.Headers.Contains("Origin")) { request.Headers.Add("Origin", request.RequestUri.GetDomain()); } if (!request.Headers.Contains("User-Agent")) { request.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"); } if (!request.Headers.Contains("Cookie") && _cookieContainer.Count > 0) { string cookieHeader = _cookieContainer.GetCookieHeader(request.RequestUri); if (!string.IsNullOrWhiteSpace(cookieHeader)) { request.Headers.Add("Cookie", cookieHeader); } } if (!request.Headers.Contains("Authorization")) { string text = TryGenerateAuthHeaderValue(request.RequestUri); if (text != null) { request.Headers.Add("Authorization", text); } } return request; } private HttpResponseMessage HandleResponse(HttpResponseMessage response) { if ((object)response.RequestMessage?.RequestUri == null) { return response; } if (response.StatusCode == HttpStatusCode.TooManyRequests) { throw new RequestLimitExceededException("Exceeded request rate limit. Please try again in a few hours. Alternatively, inject cookies corresponding to a pre-authenticated user when initializing an instance of `YoutubeClient`."); } if (response.Headers.TryGetValues("Set-Cookie", out IEnumerable<string> values)) { foreach (string item in values) { try { _cookieContainer.SetCookies(response.RequestMessage.RequestUri, item); } catch (CookieException) { } } } return response; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { int retriesRemaining = 5; HttpResponseMessage response; while (true) { response = HandleResponse(await base.SendAsync(HandleRequest(request), cancellationToken)); if (response.StatusCode < HttpStatusCode.InternalServerError || retriesRemaining <= 0) { break; } response.Dispose(); retriesRemaining--; } return response; } } } namespace YoutubeExplode.Utils { internal abstract class ClientDelegatingHandler : HttpMessageHandler { [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpClient <http>P; [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool <disposeClient>P; protected ClientDelegatingHandler(HttpClient http, bool disposeClient = false) { <http>P = http; <disposeClient>P = disposeClient; base..ctor(); } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { using HttpRequestMessage clonedRequest = request.Clone(); return await <http>P.SendAsync(clonedRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken); } protected override void Dispose(bool disposing) { if (disposing && <disposeClient>P) { <http>P.Dispose(); } base.Dispose(disposing); } } internal static class Hash { public static byte[] Compute(HashAlgorithm algorithm, byte[] data) { using (algorithm) { return algorithm.ComputeHash(data); } } } internal static class Html { private static readonly HtmlParser HtmlParser = new HtmlParser(); public static IHtmlDocument Parse(string source) { return HtmlParser.ParseDocument(source); } } internal static class Http { private static readonly Lazy<HttpClient> HttpClientLazy = new Lazy<HttpClient>(() => new HttpClient()); public static HttpClient Client => HttpClientLazy.Value; } internal static class Json { public static string Extract(string source) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; bool flag = false; foreach (var item3 in source.Index()) { int item = item3.index; char item2 = item3.value; char c = ((item > 0) ? source[item - 1] : '\0'); stringBuilder.Append(item2); if (item2 == '"' && c != '\\') { flag = !flag; } else if (item2 == '{' && !flag) { num++; } else if (item2 == '}' && !flag) { num--; } if (num == 0) { break; } } return stringBuilder.ToString(); } public static JsonElement Parse(string source) { using JsonDocument jsonDocument = JsonDocument.Parse(source); return jsonDocument.RootElement.Clone(); } public static JsonElement? TryParse(string source) { try { return Parse(source); } catch (JsonException) { return null; } } public static string Encode(string value) { StringBuilder stringBuilder = new StringBuilder(value.Length); foreach (char c in value) { switch (c) { case '\n': stringBuilder.Append("\\n"); break; case '\r': stringBuilder.Append("\\r"); break; case '\t': stringBuilder.Append("\\t"); break; case '\\': stringBuilder.Append("\\\\"); break; case '"': stringBuilder.Append("\\\""); break; default: stringBuilder.Append(c); break; } } return stringBuilder.ToString(); } public static string Serialize(string? value) { return (value != null) ? ("\"" + Encode(value) + "\"") : "null"; } public static string Serialize(int? value) { return value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : "null"; } } internal static class UrlEx { [CompilerGenerated] private sealed class <EnumerateQueryParameters>d__0 : IEnumerable<KeyValuePair<string, string>>, IEnumerable, IEnumerator<KeyValuePair<string, string>>, IEnumerator, IDisposable { private int <>1__state; private KeyValuePair<string, string> <>2__current; private int <>l__initialThreadId; private string url; public string <>3__url; private string <query>5__1; private string[] <>s__2; private int <>s__3; private string <parameter>5__4; private string <key>5__5; private string <value>5__6; KeyValuePair<string, string> IEnumerator<KeyValuePair<string, string>>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateQueryParameters>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <query>5__1 = null; <>s__2 = null; <parameter>5__4 = null; <key>5__5 = null; <value>5__6 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <key>5__5 = null; <value>5__6 = null; <parameter>5__4 = null; goto IL_0114; } <>1__state = -1; <query>5__1 = (PolyfillExtensions.Contains(url, '?') ? url.SubstringAfter("?") : url); <>s__2 = <query>5__1.Split(new char[1] { '&' }); <>s__3 = 0; goto IL_0122; IL_0114: <>s__3++; goto IL_0122; IL_0122: if (<>s__3 < <>s__2.Length) { <parameter>5__4 = <>s__2[<>s__3]; <key>5__5 = WebUtility.UrlDecode(<parameter>5__4.SubstringUntil("=")); <value>5__6 = WebUtility.UrlDecode(<parameter>5__4.SubstringAfter("=")); if (string.IsNullOrWhiteSpace(<key>5__5)) { goto IL_0114; } <>2__current = new KeyValuePair<string, string>(<key>5__5, <value>5__6); <>1__state = 1; return true; } <>s__2 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() { <EnumerateQueryParameters>d__0 <EnumerateQueryParameters>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateQueryParameters>d__ = this; } else { <EnumerateQueryParameters>d__ = new <EnumerateQueryParameters>d__0(0); } <EnumerateQueryParameters>d__.url = <>3__url; return <EnumerateQueryParameters>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<KeyValuePair<string, string>>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<EnumerateQueryParameters>d__0))] private static IEnumerable<KeyValuePair<string, string>> EnumerateQueryParameters(string url) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateQueryParameters>d__0(-2) { <>3__url = url }; } public static IReadOnlyDictionary<string, string> GetQueryParameters(string url) { return EnumerateQueryParameters(url).ToDictionary<KeyValuePair<string, string>, string, string>((KeyValuePair<string, string> kvp) => kvp.Key, (KeyValuePair<string, string> kvp) => kvp.Value); } private static KeyValuePair<string, string>? TryGetQueryParameter(string url, string key) { foreach (KeyValuePair<string, string> item in EnumerateQueryParameters(url)) { if (string.Equals(item.Key, key, StringComparison.Ordinal)) { return item; } } return null; } public static string? TryGetQueryParameterValue(string url, string key) { return TryGetQueryParameter(url, key)?.Value; } public static bool ContainsQueryParameter(string url, string key) { return TryGetQueryParameterValue(url, key) != null; } public static string RemoveQueryParameter(string url, string key) { if (!ContainsQueryParameter(url, key)) { return url; } UriBuilder uriBuilder = new UriBuilder(url); StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, string> item in EnumerateQueryParameters(url)) { if (!string.Equals(item.Key, key, StringComparison.Ordinal)) { stringBuilder.Append((stringBuilder.Length > 0) ? '&' : '?'); stringBuilder.Append(Uri.EscapeDataString(item.Key)); stringBuilder.Append('='); stringBuilder.Append(Uri.EscapeDataString(item.Value)); } } uriBuilder.Query = stringBuilder.ToString(); return uriBuilder.ToString(); } public static string SetQueryParameter(string url, string key, string value) { string text = RemoveQueryParameter(url, key); bool flag = PolyfillExtensions.Contains(text, '?'); return text + (flag ? '&' : '?') + Uri.EscapeDataString(key) + "=" + Uri.EscapeDataString(value); } } internal static class Xml { public static XElement Parse(string source) { return XElement.Parse(source, LoadOptions.PreserveWhitespace).StripNamespaces(); } } } namespace YoutubeExplode.Utils.Extensions { internal static class AsyncCollectionExtensions { public static async IAsyncEnumerable<T> TakeAsync<T>(this IAsyncEnumerable<T> source, int count) { int currentCount = 0; await foreach (T i in source) { if (currentCount >= count) { break; } yield return i; currentCount++; } } public static async IAsyncEnumerable<T> SelectManyAsync<TSource, T>(this IAsyncEnumerable<TSource> source, Func<TSource, IEnumerable<T>> transform) { await foreach (TSource i in source) { foreach (T item in transform(i)) { yield return item; } } } public static async IAsyncEnumerable<T> OfTypeAsync<T>(this IAsyncEnumerable<object> source) { T match = default(T); await foreach (object i in source) { int num; if (i is T) { match = (T)i; num = 1; } else { num = 0; } if (num != 0) { yield return match; } match = default(T); } } public static async ValueTask<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> source) { List<T> list = new List<T>(); await foreach (T i in source) { list.Add(i); } return list; } public static ValueTaskAwaiter<List<T>> GetAwaiter<T>(this IAsyncEnumerable<T> source) { return source.ToListAsync().GetAwaiter(); } } internal static class BinaryExtensions { public static string ToHex(this byte[] data, bool isUpperCase = true) { StringBuilder stringBuilder = new StringBuilder(2 * data.Length); foreach (byte b in data) { stringBuilder.Append(b.ToString(isUpperCase ? "X2" : "x2", CultureInfo.InvariantCulture)); } return stringBuilder.ToString(); } } internal static class CollectionExtensions { [CompilerGenerated] private sealed class <WhereNotNull>d__0<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable where T : class { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; private IEnumerable<T?> source; public IEnumerable<T?> <>3__source; private IEnumerator<T?> <>s__1; private T <i>5__2; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WhereNotNull>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>s__1 = null; <i>5__2 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; goto IL_0084; } <>1__state = -1; <>s__1 = source.GetEnumerator(); <>1__state = -3; goto IL_0091; IL_0084: <i>5__2 = null; goto IL_0091; IL_0091: if (<>s__1.MoveNext()) { <i>5__2 = <>s__1.Current; if (<i>5__2 != null) { <>2__current = <i>5__2; <>1__state = 1; return true; } goto IL_0084; } <>m__Finally1(); <>s__1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__1 != null) { <>s__1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<T> IEnumerable<T>.GetEnumerator() { <WhereNotNull>d__0<T> <WhereNotNull>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <WhereNotNull>d__ = this; } else { <WhereNotNull>d__ = new <WhereNotNull>d__0<T>(0); } <WhereNotNull>d__.source = <>3__source; return <WhereNotNull>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <WhereNotNull>d__1<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable where T : struct { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; private IEnumerable<T?> source; public IEnumerable<T?> <>3__source; private IEnumerator<T?> <>s__1; private T? <i>5__2; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WhereNotNull>d__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>s__1 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>s__1 = source.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>s__1.MoveNext()) { <i>5__2 = <>s__1.Current; if (<i>5__2.HasValue) { <>2__current = <i>5__2.Value; <>1__state = 1; return true; } } <>m__Finally1(); <>s__1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__1 != null) { <>s__1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<T> IEnumerable<T>.GetEnumerator() { <WhereNotNull>d__1<T> <WhereNotNull>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <WhereNotNull>d__ = this; } else { <WhereNotNull>d__ = new <WhereNotNull>d__1<T>(0); } <WhereNotNull>d__.source = <>3__source; return <WhereNotNull>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<WhereNotNull>d__0<>))] public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source) where T : class { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WhereNotNull>d__0<T>(-2) { <>3__source = source }; } [IteratorStateMachine(typeof(<WhereNotNull>d__1<>))] public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source) where T : struct { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WhereNotNull>d__1<T>(-2) { <>3__source = source }; } public static T? ElementAtOrNull<T>(this IEnumerable<T> source, int index) where T : struct { IReadOnlyList<T> readOnlyList = (source as IReadOnlyList<T>) ?? source.ToArray(); return (index < readOnlyList.Count) ? new T?(readOnlyList[index]) : null; } public static T? FirstOrNull<T>(this IEnumerable<T> source) where T : struct { using (IEnumerator<T> enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) { return enumerator.Current; } } return null; } } internal static class GenericExtensions { public static TOut Pipe<TIn, TOut>(this TIn input, Func<TIn, TOut> transform) { return transform(input); } } internal static class HttpExtensions { private class NonDisposableHttpContent : HttpContent { [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpContent <content>P; public NonDisposableHttpContent(HttpContent content) { <content>P = content; base..ctor(); } protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context) { await <content>P.CopyToAsync(stream); } protected override bool TryComputeLength(out long length) { length = 0L; return false; } } public static HttpRequestMessage Clone(this HttpRequestMessage request) { HttpRequestMessage httpRequestMessage = new HttpRequestMessage(request.Method, request.RequestUri) { Version = request.Version, Content = ((request.Content != null) ? new NonDisposableHttpContent(request.Content) : null) }; string key; IEnumerable<string> value; foreach (KeyValuePair<string, IEnumerable<string>> header in request.Headers) { PolyfillExtensions.Deconstruct(header, out key, out value); string name = key; IEnumerable<string> values = value; httpRequestMessage.Headers.TryAddWithoutValidation(name, values); } if (request.Content != null && httpRequestMessage.Content != null) { foreach (KeyValuePair<string, IEnumerable<string>> header2 in request.Content.Headers) { PolyfillExtensions.Deconstruct(header2, out key, out value); string name2 = key; IEnumerable<string> values2 = value; httpRequestMessage.Content.Headers.TryAddWithoutValidation(name2, values2); } } return httpRequestMessage; } public static async ValueTask<HttpResponseMessage> HeadAsync(this HttpClient http, string requestUri, CancellationToken cancellationToken = default(CancellationToken)) { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, requestUri); return await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); } } internal static class JsonExtensions { [CompilerGenerated] private sealed class <>c__DisplayClass9_0 { public string propertyName; internal IEnumerable<JsonElement> <EnumerateDescendantProperties>b__0(JsonElement j) { return j.EnumerateDescendantProperties(propertyName); } internal IEnumerable<JsonElement> <EnumerateDescendantProperties>b__1(JsonProperty j) { return j.Value.EnumerateDescendantProperties(propertyName); } } [CompilerGenerated] private sealed class <EnumerateDescendantProperties>d__9 : IEnumerable<JsonElement>, IEnumerable, IEnumerator<JsonElement>, IEnumerator, IDisposable { private int <>1__state; private JsonElement <>2__current; private int <>l__initialThreadId; private JsonElement element; public JsonElement <>3__element; private string propertyName; public string <>3__propertyName; private <>c__DisplayClass9_0 <>8__1; private JsonElement? <property>5__2; private IEnumerable<JsonElement> <deepArrayDescendants>5__3; private IEnumerable<JsonElement> <deepObjectDescendants>5__4; private IEnumerator<JsonElement> <>s__5; private JsonElement <deepDescendant>5__6; private IEnumerator<JsonElement> <>s__7; private JsonElement <deepDescendant>5__8; JsonElement IEnumerator<JsonElement>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateDescendantProperties>d__9(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 2: try { } finally { <>m__Finally1(); } break; case -4: case 3: try { } finally { <>m__Finally2(); } break; } <>8__1 = null; <deepArrayDescendants>5__3 = null; <deepObjectDescendants>5__4 = null; <>s__5 = null; <deepDescendant>5__6 = default(JsonElement); <>s__7 = null; <deepDescendant>5__8 = default(JsonElement); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass9_0(); <>8__1.propertyName = propertyName; <property>5__2 = element.GetPropertyOrNull(<>8__1.propertyName); if (<property>5__2.HasValue) { <>2__current = <property>5__2.Value; <>1__state = 1; return true; } goto IL_00a9; case 1: <>1__state = -1; goto IL_00a9; case 2: <>1__state = -3; <deepDescendant>5__6 = default(JsonElement); goto IL_0130; case 3: { <>1__state = -4; <deepDescendant>5__8 = default(JsonElement); break; } IL_00a9: <deepArrayDescendants>5__3 = element.EnumerateArrayOrEmpty().SelectMany((JsonElement j) => j.EnumerateDescendantProperties(<>8__1.propertyName)); <>s__5 = <deepArrayDescendants>5__3.GetEnumerator(); <>1__state = -3; goto IL_0130; IL_0130: if (<>s__5.MoveNext()) { <deepDescendant>5__6 = <>s__5.Current; <>2__current = <deepDescendant>5__6; <>1__state = 2; return true; } <>m__Finally1(); <>s__5 = null; <deepObjectDescendants>5__4 = element.EnumerateObjectOrEmpty().SelectMany((JsonProperty j) => j.Value.EnumerateDescendantProperties(<>8__1.propertyName)); <>s__7 = <deepObjectDescendants>5__4.GetEnumerator(); <>1__state = -4; break; } if (<>s__7.MoveNext()) { <deepDescendant>5__8 = <>s__7.Current; <>2__current = <deepDescendant>5__8; <>1__state = 3; return true; } <>m__Finally2(); <>s__7 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__5 != null) { <>s__5.Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<>s__7 != null) { <>s__7.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<JsonElement> IEnumerable<JsonElement>.GetEnumerator() { <EnumerateDescendantProperties>d__9 <EnumerateDescendantProperties>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateDescendantProperties>d__ = this; } else { <EnumerateDescendantProperties>d__ = new <EnumerateDescendantProperties>d__9(0); } <EnumerateDescendantProperties>d__.element = <>3__element; <EnumerateDescendantProperties>d__.propertyName = <>3__propertyName; return <EnumerateDescendantProperties>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<JsonElement>)this).GetEnumerator(); } } public static JsonElement? GetPropertyOrNull(this JsonElement element, string propertyName) { if (element.ValueKind != JsonValueKind.Object) { return null; } if (element.TryGetProperty(propertyName, out var value) && value.ValueKind != JsonValueKind.Null && value.ValueKind != 0) { return value; } return null; } public static bool? GetBooleanOrNull(this JsonElement element) { JsonValueKind valueKind = element.ValueKind; if (1 == 0) { } bool? result = valueKind switch { JsonValueKind.True => true, JsonValueKind.False => false, _ => null, }; if (1 == 0) { } return result; } public static string? GetStringOrNull(this JsonElement element) { return (element.ValueKind == JsonValueKind.String) ? element.GetString() : null; } public static int? GetInt32OrNull(this JsonElement element) { int value; return (element.ValueKind == JsonValueKind.Number && element.TryGetInt32(out value)) ? new int?(value) : null; } public static long? GetInt64OrNull(this JsonElement element) { long value; return (element.ValueKind == JsonValueKind.Number && element.TryGetInt64(out value)) ? new long?(value) : null; } public static JsonElement.ArrayEnumerator? EnumerateArrayOrNull(this JsonElement element) { return (element.ValueKind == JsonValueKind.Array) ? new JsonElement.ArrayEnumerator?(element.EnumerateArray()) : null; } public static JsonElement.ArrayEnumerator EnumerateArrayOrEmpty(this JsonElement element) { return element.EnumerateArrayOrNull().GetValueOrDefault(); } public static JsonElement.ObjectEnumerator? EnumerateObjectOrNull(this JsonElement element) { return (element.ValueKind == JsonValueKind.Object) ? new JsonElement.ObjectEnumerator?(element.EnumerateObject()) : null; } public static JsonElement.ObjectEnumerator EnumerateObjectOrEmpty(this JsonElement element) { return element.EnumerateObjectOrNull().GetValueOrDefault(); } [IteratorStateMachine(typeof(<EnumerateDescendantProperties>d__9))] public static IEnumerable<JsonElement> EnumerateDescendantProperties(this JsonElement element, string propertyName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateDescendantProperties>d__9(-2) { <>3__element = element, <>3__propertyName = propertyName }; } } internal static class StreamExtensions { public static async ValueTask CopyToAsync(this Stream source, Stream destination, IProgress<double>? progress = null, CancellationToken cancellationToken = default(CancellationToken)) { using IMemoryOwner<byte> buffer = MemoryPool<byte>.Shared.Rent(81920); long totalBytesRead = 0L; while (true) { int bytesRead = await PolyfillExtensions.ReadAsync(source, buffer.Memory, cancellationToken); if (bytesRead <= 0) { break; } await PolyfillExtensions.WriteAsync(destination, buffer.Memory.Slice(0, bytesRead), cancellationToken); totalBytesRead += bytesRead; progress?.Report(1.0 * (double)totalBytesRead / (double)source.Length); } } } internal static class StringExtensions { public static string? NullIfWhiteSpace(this string str) { return (!string.IsNullOrWhiteSpace(str)) ? str : null; } public static string SubstringUntil(this string str, string sub, StringComparison comparison = StringComparison.Ordinal) { int num = str.IndexOf(sub, comparison); return (num < 0) ? str : str.Substring(0, num); } public static string SubstringAfter(this string str, string sub, StringComparison comparison = StringComparison.Ordinal) { int num = str.IndexOf(sub, comparison); return (num < 0) ? string.Empty : str.Substring(num + sub.Length, str.Length - num - sub.Length); } public static string StripNonDigit(this string str) { StringBuilder stringBuilder = new StringBuilder(); foreach (char item in str.Where(char.IsDigit)) { stringBuilder.Append(item); } return stringBuilder.ToString(); } public static string Reverse(this string str) { StringBuilder stringBuilder = new StringBuilder(str.Length); for (int num = str.Length - 1; num >= 0; num--) { stringBuilder.Append(str[num]); } return stringBuilder.ToString(); } public static string SwapChars(this string str, int firstCharIndex, int secondCharIndex) { return new StringBuilder(str) { [firstCharIndex] = str[secondCharIndex], [secondCharIndex] = str[firstCharIndex] }.ToString(); } public static int? ParseIntOrNull(this string str) { int result; return int.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result) ? new int?(result) : null; } public static int ParseInt(this string str) { return str.ParseIntOrNull() ?? throw new FormatException("Cannot parse integer number from string '" + str + "'."); } public static long? ParseLongOrNull(this string str) { long result; return long.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result) ? new long?(result) : null; } public static double? ParseDoubleOrNull(this string str) { double result; return double.TryParse(str, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.InvariantInfo, out result) ? new double?(result) : null; } public static TimeSpan? ParseTimeSpanOrNull(this string str, string[] formats) { TimeSpan result; return TimeSpan.TryParseExact(str, formats, DateTimeFormatInfo.InvariantInfo, out result) ? new TimeSpan?(result) : null; } public static DateTimeOffset? ParseDateTimeOffsetOrNull(this string str) { DateTimeOffset result; return DateTimeOffset.TryParse(str, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out result) ? new DateTimeOffset?(result) : null; } public static string ConcatToString<T>(this IEnumerable<T> source) { return string.Concat(source); } } internal static class UriExtensions { public static string GetDomain(this Uri uri) { return uri.Scheme + Uri.SchemeDelimiter + uri.Host; } } internal static class XElementExtensions { public static XElement StripNamespaces(this XElement element) { XElement xElement = new XElement(element); foreach (XElement item in xElement.DescendantsAndSelf()) { item.Name = XNamespace.None.GetName(item.Name.LocalName); item.ReplaceAttributes(from a in item.Attributes() where !a.IsNamespaceDeclaration where a.Name.Namespace != XNamespace.Xml && a.Name.Namespace != XNamespace.Xmlns select new XAttribute(XNamespace.None.GetName(a.Name.LocalName), a.Value)); } return xElement; } } } namespace YoutubeExplode.Search { public class ChannelSearchResult : ISearchResult, IBatchItem, IChannel { public ChannelId Id { get; } public string Url => $"https://www.youtube.com/channel/{Id}"; public string Title { get; } public IReadOnlyList<Thumbnail> Thumbnails { get; } public ChannelSearchResult(ChannelId id, string title, IReadOnlyList<Thumbnail> thumbnails) { Id = id; Title = title; Thumbnails = thumbnails; base..ctor(); } [ExcludeFromCodeCoverage] public override string ToString() { return "Channel (" + Title + ")"; } } public interface ISearchResult : IBatchItem { string Url { get; } string Title { get; } } public class PlaylistSearchResult : ISearchResult, IBatchItem, IPlaylist { public PlaylistId Id { get; } public string Url => $"https://www.youtube.com/playlist?list={Id}"; public string Title { get; } public Author? Author { get; } public IReadOnlyList<Thumbnail> Thumbnails { get; } public PlaylistSearchResult(PlaylistId id, string title, Author? author, IReadOnlyList<Thumbnail> thumbnails) { Id = id; Title = title; Author = author; Thumbnails = thumbnails; base..ctor(); } [ExcludeFromCodeCoverage] public override string ToString() { return "Playlist (" + Title + ")"; } } public class SearchClient { [CompilerGenerated] private sealed class <GetResultBatchesAsync>d__2 : IAsyncEnumerable<Batch<ISearchResult>>, IAsyncEnumerator<Batch<ISearchResult>>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private Batch<ISearchResult> <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; private string searchQuery; public string <>3__searchQuery; private SearchFilter searchFilter; public SearchFilter <>3__searchFilter; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; public SearchClient <>4__this; private HashSet<string> <encounteredIds>5__1; private string <continuationToken>5__2; private List<ISearchResult> <results>5__3; private SearchResponse <searchResults>5__4; private SearchResponse <>s__5; private IEnumerator<SearchResponse.VideoData> <>s__6; private SearchResponse.VideoData <videoData>5__7; private string <videoId>5__8; private string <videoTitle>5__9; private string <videoChannelTitle>5__10; private string <videoChannelId>5__11; private Thumbnail[] <videoThumbnails>5__12; private VideoSearchResult <video>5__13; private IEnumerator<SearchResponse.PlaylistData> <>s__14; private SearchResponse.PlaylistData <playlistData>5__15; private string <playlistId>5__16; private string <playlistTitle>5__17; private Author <playlistAuthor>5__18; private Thumbnail[] <playlistThumbnails>5__19; private PlaylistSearchResult <playlist>5__20; private IEnumerator<SearchResponse.ChannelData> <>s__21; private SearchResponse.ChannelData <channelData>5__22; private string <channelId>5__23; private string <channelTitle>5__24; private Thumbnail[] <channelThumbnails>5__25; private ChannelSearchResult <channel>5__26; private ValueTaskAwaiter<SearchResponse> <>u__1; Batch<ISearchResult> IAsyncEnumerator<Batch<ISearchResult>>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetResultBatchesAsync>d__2(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; try { ValueTaskAwaiter<SearchResponse> awaiter; switch (num) { default: if (!<>w__disposeMode) { num = (<>1__state = -1); <encounteredIds>5__1 = new HashSet<string>(StringComparer.Ordinal); <continuationToken>5__2 = null; goto IL_0060; } goto end_IL_0007; case 0: awaiter = <>u__1; <>u__1 = default(ValueTaskAwaiter<SearchResponse>); num = (<>1__state = -1); break; case -4: { num = (<>1__state = -1); if (!<>w__disposeMode) { <continuationToken>5__2 = <searchResults>5__4.ContinuationToken; <results>5__3 = null; <searchResults>5__4 = null; if (!string.IsNullOrWhiteSpace(<continuationToken>5__2)) { goto IL_0060; } } goto end_IL_0007; } IL_0060: <results>5__3 = new List<ISearchResult>(); <>2__current = null; awaiter = <>4__this._controller.GetSearchResponseAsync(searchQuery, searchFilter, <continuationToken>5__2, cancellationToken).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetResultBatchesAsync>d__2 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } break; } <>s__5 = awaiter.GetResult(); <searchResults>5__4 = <>s__5; <>s__5 = null; <>s__6 = <searchResults>5__4.Videos.GetEnumerator(); try { while (<>s__6.MoveNext()) { <videoData>5__7 = <>s__6.Current; if (searchFilter != 0 && searchFilter != SearchFilter.Video) { Debug.Fail("Did not expect videos in search results."); break; } <videoId>5__8 = <videoData>5__7.Id ?? throw new YoutubeExplodeException("Failed to extract the video ID."); if (<encounteredIds>5__1.Add(<videoId>5__8)) { <videoTitle>5__9 = <videoData>5__7.Title ?? throw new YoutubeExplodeException("Failed to extract the video title."); <videoChannelTitle>5__10 = <videoData>5__7.Author ?? throw new YoutubeExplodeException("Failed to extract the video author."); <videoChannelId>5__11 = <videoData>5__7.ChannelId ?? throw new YoutubeExplodeException("Failed to extract the video channel ID."); <videoThumbnails>5__12 = <videoData>5__7.Thumbnails.Select(delegate(ThumbnailData t) { string url3 = t.Url ?? throw new YoutubeExplodeException("Failed to extract the video thumbnail URL."); int width3 = t.Width ?? throw new YoutubeExplodeException("Failed to extract the video thumbnail width."); int height3 = t.Height ?? throw new YoutubeExplodeException("Failed to extract the video thumbnail height."); Resolution resolution3 = new Resolution(width3, height3); return new Thumbnail(url3, resolution3); }).Concat(Thumbnail.GetDefaultSet(<videoId>5__8)).ToArray(); <video>5__13 = new VideoSearchResult(<videoId>5__8, <videoTitle>5__9, new Author(<videoChannelId>5__11, <videoChannelTitle>5__10), <videoData>5__7.Duration, <videoThumbnails>5__12); <results>5__3.Add(<video>5__13); <videoId>5__8 = null; <videoTitle>5__9 = null; <videoChannelTitle>5__10 = null; <videoChannelId>5__11 = null; <videoThumbnails>5__12 = null; <video>5__13 = null; <videoData>5__7 = null; } } } finally { if (num == -1 && <>s__6 != null) { <>s__6.Dispose(); } } if (!<>w__disposeMode) { <>s__6 = null; <>s__14 = <searchResults>5__4.Playlists.GetEnumerator(); try { while (<>s__14.MoveNext()) { <playlistData>5__15 = <>s__14.Current; if (searchFilter != 0 && searchFilter != SearchFilter.Playlist) { Debug.Fail("Did not expect playlists in search results."); break; } <playlistId>5__16 = <playlistData>5__15.Id ?? throw new YoutubeExplodeException("Failed to extract the playlist ID."); if (<encounteredIds>5__1.Add(<playlistId>5__16)) { <playlistTitle>5__17 = <playlistData>5__15.Title ?? throw new YoutubeExplodeException("Failed to extract the playlist title."); <playlistAuthor>5__18 = ((!string.IsNullOrWhiteSpace(<playlistData>5__15.ChannelId) && !string.IsNullOrWhiteSpace(<playlistData>5__15.Author)) ? new Author(<playlistData>5__15.ChannelId, <playlistData>5__15.Author) : null); <playlistThumbnails>5__19 = <playlistData>5__15.Thumbnails.Select(delegate(ThumbnailData t) { string url2 = t.Url ?? throw new YoutubeExplodeException("Failed to extract the playlist thumbnail URL."); int width2 = t.Width ?? throw new YoutubeExplodeException("Failed to extract the playlist thumbnail width."); int height2 = t.Height ?? throw new YoutubeExplodeException("Failed to extract the playlist thumbnail height."); Resolution resolution2 = new Resolution(width2, height2); return new Thumbnail(url2, resolution2); }).ToArray(); <playlist>5__20 = new PlaylistSearchResult(<playlistId>5__16, <playlistTitle>5__17, <playlistAuthor>5__18, <playlistThumbnails>5__19); <results>5__3.Add(<playlist>5__20); <playlistId>5__16 = null; <playlistTitle>5__17 = null; <playlistAuthor>5__18 = null; <playlistThumbnails>5__19 = null; <playlist>5__20 = null; <playlistData>5__15 = null; } } } finally { if (num == -1 && <>s__14 != null) { <>s__14.Dispose(); } } if (!<>w__disposeMode) { <>s__14 = null; <>s__21 = <searchResults>5__4.Channels.GetEnumerator(); try { while (<>s__21.MoveNext()) { <channelData>5__22 = <>s__21.Current; if (searchFilter != 0 && searchFilter != SearchFilter.Channel) { Debug.Fail("Did not expect channels in search results."); break; } <channelId>5__23 = <channelData>5__22.Id ?? throw new YoutubeExplodeException("Failed to extract the channel ID."); <channelTitle>5__24 = <channelData>5__22.Title ?? throw new YoutubeExplodeException("Failed to extract the channel title."); <channelThumbnails>5__25 = <channelData>5__22.Thumbnails.Select(delegate(ThumbnailData t) { string url = t.Url ?? throw new YoutubeExplodeException("Failed to extract the channel thumbnail URL."); int width = t.Width ?? throw new YoutubeExplodeException("Failed to extract the channel thumbnail width."); int height = t.Height ?? throw new YoutubeExplodeException("Failed to extract the channel thumbnail height."); Resolution resolution = new Resolution(width, height); return new Thumbnail(url, resolution); }).ToArray(); <channel>5__26 = new ChannelSearchResult(<channelId>5__23, <channelTitle>5__24, <channelThumbnails>5__25); <results>5__3.Add(<channel>5__26); <channelId>5__23 = null; <channelTitle>5__24 = null; <channelThumbnails>5__25 = null; <channel>5__26 = null; <channelData>5__22 = null; } } finally { if (num == -1 && <>s__21 != null) { <>s__21.Dispose(); } } if (!<>w__disposeMode) { <>s__21 = null; <>2__current = Batch.Create(<results>5__3); num = (<>1__state = -4); goto IL_08e0; } } } end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <encounteredIds>5__1 = null; <continuationToken>5__2 = null; <results>5__3 = null; <searchResults>5__4 = null; <>s__5 = null; <>s__6 = null; <videoData>5__7 = null; <videoId>5__8 = null; <videoTitle>5__9 = null; <videoChannelTitle>5__10 = null; <videoChannelId>5__11 = null; <videoThumbnails>5__12 = null; <video>5__13 = null; <>s__14 = null; <playlistData>5__15 = null; <playlistId>5__16 = null; <playlistTitle>5__17 = null; <playlistAuthor>5__18 = null; <playlistThumbnails>5__19 = null; <playlist>5__20 = null; <>s__21 = null; <channelData>5__22 = null; <channelId>5__23 = null; <channelTitle>5__24 = null; <channelThumbnails>5__25 = null; <channel>5__26 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <encounteredIds>5__1 = null; <continuationToken>5__2 = null; <results>5__3 = null; <searchResults>5__4 = null; <>s__5 = null; <>s__6 = null; <videoData>5__7 = null; <videoId>5__8 = null; <videoTitle>5__9 = null; <videoChannelTitle>5__10 = null; <videoChannelId>5__11 = null; <videoThumbnails>5__12 = null; <video>5__13 = null; <>s__14 = null; <playlistData>5__15 = null; <playlistId>5__16 = null; <playlistTitle>5__17 = null; <playlistAuthor>5__18 = null; <playlistThumbnails>5__19 = null; <playlist>5__20 = null; <>s__21 = null; <channelData>5__22 = null; <channelId>5__23 = null; <channelTitle>5__24 = null; <channelThumbnails>5__25 = null; <channel>5__26 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_08e0: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<Batch<ISearchResult>> IAsyncEnumerable<Batch<ISearchResult>>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetResultBatchesAsync>d__2 <GetResultBatchesAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetResultBatchesAsync>d__ = this; } else { <GetResultBatchesAsync>d__ = new <GetResultBatchesAsync>d__2(-3) { <>4__this = <>4__this }; } <GetResultBatchesAsync>d__.searchQuery = <>3__searchQuery; <GetResultBatchesAsync>d__.searchFilter = <>3__searchFilter; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetResultBatchesAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetResultBatchesAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetResultBatchesAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetResultBatchesAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<Batch<ISearchResult>>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetResultBatchesAsync>d__2 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetResultBatchesAsync>d__2 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } private readonly SearchController _controller = new SearchController(http); public SearchClient(HttpClient http) { } [AsyncIteratorStateMachine(typeof(<GetResultBatchesAsync>d__2))] public IAsyncEnumerable<Batch<ISearchResult>> GetResultBatchesAsync(string searchQuery, SearchFilter searchFilter, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetResultBatchesAsync>d__2(-2) { <>4__this = this, <>3__searchQuery = searchQuery, <>3__searchFilter = searchFilter, <>3__cancellationToken = cancellationToken }; } public IAsyncEnumerable<Batch<ISearchResult>> GetResultBatchesAsync(string searchQuery, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, SearchFilter.None, cancellationToken); } public IAsyncEnumerable<ISearchResult> GetResultsAsync(string searchQuery, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, cancellationToken).FlattenAsync(); } public IAsyncEnumerable<VideoSearchResult> GetVideosAsync(string searchQuery, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, SearchFilter.Video, cancellationToken).FlattenAsync().OfTypeAsync<VideoSearchResult>(); } public IAsyncEnumerable<PlaylistSearchResult> GetPlaylistsAsync(string searchQuery, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, SearchFilter.Playlist, cancellationToken).FlattenAsync().OfTypeAsync<PlaylistSearchResult>(); } public IAsyncEnumerable<ChannelSearchResult> GetChannelsAsync(string searchQuery, CancellationToken cancellationToken = default(CancellationToken)) { return GetResultBatchesAsync(searchQuery, SearchFilter.Channel, cancellationToken).FlattenAsync().OfTypeAsync<ChannelSearchResult>(); } } internal class SearchController { [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpClient <http>P; public SearchController(HttpClient http) { <http>P = http; base..ctor(); } public async ValueTask<SearchResponse> GetSearchResponseAsync(string searchQuery, SearchFilter searchFilter, string? continuationToken, CancellationToken cancellationToken = default(CancellationToken)) { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://www.youtube.com/youtubei/v1/search"); HttpRequestMessage httpRequestMessage = request; string text = Json.Serialize(searchQuery); if (1 == 0) { } string value = searchFilter switch { SearchFilter.Video => "EgIQAQ%3D%3D", SearchFilter.Playlist => "EgIQAw%3D%3D", SearchFilter.Channel => "EgIQAg%3D%3D", _ => null, }; if (1 == 0) { } httpRequestMessage.Content = new StringContent("{\r\n \"query\": " + text + ",\r\n \"params\": " + Json.Serialize(value) + ",\r\n \"continuation\": " + Json.Serialize(continuationToken) + ",\r\n \"context\": {\r\n \"client\": {\r\n \"clientName\": \"WEB\",\r\n \"clientVersion\": \"2.20210408.08.00\",\r\n \"hl\": \"en\",\r\n \"gl\": \"US\",\r\n \"utcOffsetMinutes\": 0\r\n }\r\n }\r\n}"); using HttpResponseMessage response = await <http>P.SendAsync(request, cancellationToken); response.EnsureSuccessStatusCode(); return SearchResponse.Parse(await PolyfillExtensions.ReadAsStringAsync(response.Content, cancellationToken)); } } public enum SearchFilter { None, Video, Playlist, Channel } public class VideoSearchResult : ISearchResult, IBatchItem, IVideo { public VideoId Id { get; } public string Url => $"https://www.youtube.com/watch?v={Id}"; public string Title { get; } public Author Author { get; } public TimeSpan? Duration { get; } public IReadOnlyList<Thumbnail> Thumbnails { get; } public VideoSearchResult(VideoId id, string title, Author author, TimeSpan? duration, IReadOnlyList<Thumbnail> thumbnails) { Id = id; Title = title; Author = author; Duration = duration; Thumbnails = thumbnails; base..ctor(); } [ExcludeFromCodeCoverage] public override string ToString() { return "Video (" + Title + ")"; } } } namespace YoutubeExplode.Playlists { public interface IPlaylist { PlaylistId Id { get; } string Url { get; } string Title { get; } Author? Author { get; } IReadOnlyList<Thumbnail> Thumbnails { get; } } public class Playlist : IPlaylist { public PlaylistId Id { get; } public string Url => $"https://www.youtube.com/playlist?list={Id}"; public string Title { get; } public Author? Author { get; } public string Description { get; } public int? Count { get; } public IReadOnlyList<Thumbnail> Thumbnails { get; } public Playlist(PlaylistId id, string title, Author? author, string description, int? count, IReadOnlyList<Thumbnail> thumbnails) { Id = id; Title = title; Author = author; Description = description; Count = count; Thumbnails = thumbnails; base..ctor(); } [ExcludeFromCodeCoverage] public override string ToString() { return "Playlist (" + Title + ")"; } } public class PlaylistClient { [CompilerGenerated] private sealed class <GetVideoBatchesAsync>d__3 : IAsyncEnumerable<Batch<PlaylistVideo>>, IAsyncEnumerator<Batch<PlaylistVideo>>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private Batch<PlaylistVideo> <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; private PlaylistId playlistId; public PlaylistId <>3__playlistId; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; public PlaylistClient <>4__this; private HashSet<VideoId> <encounteredIds>5__1; private VideoId? <lastVideoId>5__2; private int <lastVideoIndex>5__3; private string <visitorData>5__4; private PlaylistNextResponse <response>5__5; private List<PlaylistVideo> <videos>5__6; private PlaylistNextResponse <>s__7; private IEnumerator<PlaylistVideoData> <>s__8; private PlaylistVideoData <videoData>5__9; private string <videoId>5__10; private string <videoTitle>5__11; private string <videoChannelTitle>5__12; private string <videoChannelId>5__13; private Thumbnail[] <videoThumbnails>5__14; private PlaylistVideo <video>5__15; private ValueTaskAwaiter<PlaylistNextResponse> <>u__1; Batch<PlaylistVideo> IAsyncEnumerator<Batch<PlaylistVideo>>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetVideoBatchesAsync>d__3(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; try { ValueTaskAwaiter<PlaylistNextResponse> awaiter; switch (num) { default: if (!<>w__disposeMode) { num = (<>1__state = -1); <encounteredIds>5__1 = new HashSet<VideoId>(); <lastVideoId>5__2 = null; <lastVideoIndex>5__3 = 0; <visitorData>5__4 = null; goto IL_006e; } goto end_IL_0007; case 0: awaiter = <>u__1; <>u__1 = default(ValueTaskAwaiter<PlaylistNextResponse>); num = (<>1__state = -1); break; case -4: { num = (<>1__state = -1); if (!<>w__disposeMode) { if (<visitorData>5__4 == null) { <visitorData>5__4 = <response>5__5.VisitorData; } <response>5__5 = null; <videos>5__6 = null; bool flag = true; goto IL_006e; } goto end_IL_0007; } IL_006e: <>2__current = null; awaiter = <>4__this._controller.GetPlaylistNextResponseAsync(playlistId, <lastVideoId>5__2, <lastVideoIndex>5__3, <visitorData>5__4, cancellationToken).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetVideoBatchesAsync>d__3 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } break; } <>s__7 = awaiter.GetResult(); <response>5__5 = <>s__7; <>s__7 = null; <videos>5__6 = new List<PlaylistVideo>(); <>s__8 = <response>5__5.Videos.GetEnumerator(); try { while (<>s__8.MoveNext()) { <videoData>5__9 = <>s__8.Current; <videoId>5__10 = <videoData>5__9.Id ?? throw new YoutubeExplodeException("Failed to extract the video ID."); <lastVideoId>5__2 = <videoId>5__10; <lastVideoIndex>5__3 = <videoData>5__9.Index ?? throw new YoutubeExplodeException("Failed to extract the video index."); if (<encounteredIds>5__1.Add(<videoId>5__10)) { <videoTitle>5__11 = <videoData>5__9.Title ?? ""; <videoChannelTitle>5__12 = <videoData>5__9.Author ?? throw new YoutubeExplodeException("Failed to extract the video author."); <videoChannelId>5__13 = <videoData>5__9.ChannelId ?? throw new YoutubeExplodeException("Failed to extract the video channel ID."); <videoThumbnails>5__14 = <videoData>5__9.Thumbnails.Select(delegate(ThumbnailData t) { string url = t.Url ?? throw new YoutubeExplodeException("Failed to extract the thumbnail URL."); int width = t.Width ?? throw new YoutubeExplodeException("Failed to extract the thumbnail width."); int height = t.Height ?? throw new YoutubeExplodeException("Failed to extract the thumbnail height."); Resolution resolution = new Resolution(width, height); return new Thumbnail(url, resolution); }).Concat(Thumbnail.GetDefaultSet(<videoId>5__10)).ToArray(); <video>5__15 = new PlaylistVideo(playlistId, <videoId>5__10, <videoTitle>5__11, new Author(<videoChannelId>5__13, <videoChannelTitle>5__12), <videoData>5__9.Duration, <videoThumbnails>5__14); <videos>5__6.Add(<video>5__15); <videoId>5__10 = null; <videoTitle>5__11 = null; <videoChannelTitle>5__12 = null; <videoChannelId>5__13 = null; <videoThumbnails>5__14 = null; <video>5__15 = null; <videoData>5__9 = null; } } } finally { if (num == -1 && <>s__8 != null) { <>s__8.Dispose(); } } if (!<>w__disposeMode) { <>s__8 = null; if (<videos>5__6.Any()) { <>2__current = Batch.Create(<videos>5__6); num = (<>1__state = -4); goto IL_0515; } } end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <encounteredIds>5__1 = null; <visitorData>5__4 = null; <response>5__5 = null; <videos>5__6 = null; <>s__7 = null; <>s__8 = null; <videoData>5__9 = null; <videoId>5__10 = null; <videoTitle>5__11 = null; <videoChannelTitle>5__12 = null; <videoChannelId>5__13 = null; <videoThumbnails>5__14 = null; <video>5__15 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <encounteredIds>5__1 = null; <visitorData>5__4 = null; <response>5__5 = null; <videos>5__6 = null; <>s__7 = null; <>s__8 = null; <videoData>5__9 = null; <videoId>5__10 = null; <videoTitle>5__11 = null; <videoChannelTitle>5__12 = null; <videoChannelId>5__13 = null; <videoThumbnails>5__14 = null; <video>5__15 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_0515: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<Batch<PlaylistVideo>> IAsyncEnumerable<Batch<PlaylistVideo>>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetVideoBatchesAsync>d__3 <GetVideoBatchesAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetVideoBatchesAsync>d__ = this; } else { <GetVideoBatchesAsync>d__ = new <GetVideoBatchesAsync>d__3(-3) { <>4__this = <>4__this }; } <GetVideoBatchesAsync>d__.playlistId = <>3__playlistId; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetVideoBatchesAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetVideoBatchesAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetVideoBatchesAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetVideoBatchesAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<Batch<PlaylistVideo>>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetVideoBatchesAsync>d__3 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetVideoBatchesAsync>d__3 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } private readonly PlaylistController _controller = new PlaylistController(http); public PlaylistClient(HttpClient http) { } public async ValueTask<Playlist> GetAsync(PlaylistId playlistId, CancellationToken cancellationToken = default(CancellationToken)) { IPlaylistData response = await _controller.GetPlaylistResponseAsync(playlistId, cancellationToken); string title = response.Title ?? throw new YoutubeExplodeException("Failed to extract the playlist title."); string channelId = response.ChannelId; string channelTitle = response.Author; Author author = ((channelId != null && channelTitle != null) ? new Author(channelId, channelTitle) : null); string description = response.Description ?? ""; int? count = response.Count; Thumbnail[] thumbnails = response.Thumbnails.Select(delegate(ThumbnailData t) { string url = t.Url ?? throw new YoutubeExplodeException("Failed to extract the thumbnail URL."); int width = t.Width ?? throw new YoutubeExplodeException("Failed to extract the thumbnail width."); int height = t.Height ?? throw new YoutubeExplodeException("Failed to extract the thumbnail height."); Resolution resolution = new Resolution(width, height); return new Thumbnail(url, resolution); }).ToArray(); return new Playlist(playlistId, title, author, description, count, thumbnails); } [AsyncIteratorStateMachine(typeof(<GetVideoBatchesAsync>d__3))] public IAsyncEnumerable<Batch<PlaylistVideo>> GetVideoBatchesAsync(PlaylistId playlistId, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetVideoBatchesAsync>d__3(-2) { <>4__this = this, <>3__playlistId = playlistId, <>3__cancellationToken = cancellationToken }; } public IAsyncEnumerable<PlaylistVideo> GetVideosAsync(PlaylistId playlistId, CancellationToken cancellationToken = default(CancellationToken)) { return GetVideoBatchesAsync(playlistId, cancellationToken).FlattenAsync(); } } internal class PlaylistController { [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HttpClient <http>P; public PlaylistController(HttpClient http) { <http>P = http; base..ctor(); } public async ValueTask<PlaylistBrowseResponse> GetPlaylistBrowseResponseAsync(PlaylistId playlistId, CancellationToken cancellationToken = default(CancellationToken)) { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://www.youtube.com/youtubei/v1/browse"); request.Content = new StringContent("{\r\n \"browseId\": " + Json.Serialize("VL" + playlistId) + ",\r\n \"context\": {\r\n \"client\": {\r\n \"clientName\": \"WEB\",\r\n \"clientVersion\": \"2.20210408.08.00\",\r\n \"hl\": \"en\",\r\n \"gl\": \"US\",\r\n \"utcOffsetMinutes\": 0\r\n }\r\n }\r\n}"); using HttpResponseMessage response = await <http>P.SendAsync(request, cancellationToken); response.EnsureSuccessStatusCode(); PlaylistBrowseResponse playlistResponse = PlaylistBrowseResponse.Parse(await PolyfillExtensions.ReadAsStringAsync(response.Content, cancellationToken)); if (!playlistResponse.IsAvailable) { throw new PlaylistUnavailableException($"Playlist '{playlistId}' is not available."); } return playlistResponse; } public async ValueTask<PlaylistNextResponse> GetPlaylistNextResponseAsync(PlaylistId playlistId, VideoId? videoId = null, int index = 0, string? visitorData = null, CancellationToken cancellationToken = default(CancellationToken)) { int retriesRemaining = 5; while (true) { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://www.youtube.com/youtubei/v1/next")) { string[] obj = new string[9] { "{\r\n \"playlistId\": ", Json.Serialize(playlistId), ",\r\n \"videoId\": ", null, null, null, null, null, null }; VideoId? videoId2 = videoId; obj[3] = Json.Serialize(videoId2.HasValue ? ((string)videoId2.GetValueOrDefault()) : null); obj[4] = ",\r\n \"playlistIndex\": "; obj[5] = Json.Serialize(index); obj[6] = ",\r\n \"context\": {\r\n \"client\": {\r\n \"clientName\": \"WEB\",\r\n \"clientVersion\": \"2.20210408.08.00\",\r\n \"hl\": \"en\",\r\n \"gl\": \"US\",\r\n \"utcOffsetMinutes\": 0,\r\n \"visitorData\": "; obj[7] = Json.Serialize(visitorData); obj[8] = "\r\n }\r\n }\r\n}"; request.Content = new StringContent(string.Concat(obj)); using HttpResponseMessage response = await <http>P.SendAsync(request, cancellationToken); response.EnsureSuccessStatusCode(); PlaylistNextResponse playlistResponse = PlaylistNextResponse.Parse(await PolyfillExtensions.ReadAsStringAsync(response.Content, cancellationToken)); if (playlistResponse.IsAvailable) { return playlistResponse; } if (index <= 0 || string.IsNullOrWhiteSpace(visitorData) || retriesRemaining <= 0) { if (index > 0 || !string.IsNullOrWhiteSpace(visitorData) || retriesRemaining < 5) { throw new PlaylistUnavailableException($"Playlist '{playlistId}' is not available."); } using (await <http>P.GetAsync($"https://youtube.com/playlist?list={playlistId}", cancellationToken)) { } } } retriesRemaining--; } } public async ValueTask<IPlaylistData> GetPlaylistResponseAsync(PlaylistId playlistId, CancellationToken cancellationToken = default(CancellationToken)) { try { return await GetPlaylistBrowseResponseAsync(playlistId, cancellationToken); } catch (PlaylistUnavailableException) { return await GetPlaylistNextResponseAsync(playlistId, null, 0, null, cancellationToken); } } } public readonly struct PlaylistId : IEquatable<PlaylistId> { public string Value { get; } public PlaylistId(string value) { Value = value; } public override string ToString() { return Value; } private static bool IsValid(string playlistId) { return playlistId.Length >= 2 && playlistId.All(delegate(char c) { bool flag = char.IsLetterOrDigit(c); bool flag2 = flag; if (!flag2) { bool flag3 = ((c == '-' || c == '_') ? true : false); flag2 = flag3; } return flag2; }); } private static string? TryNormalize(string? playlistIdOrUrl) { if (string.IsNullOrWhiteSpace(playlistIdOrUrl)) { return null; } if (IsValid(playlistIdOrUrl)) { return playlistIdOrUrl; } string text = Regex.Match(playlistIdOrUrl, "youtube\\..+?/playlist.*?list=(.*?)(?:&|/|$)").Groups[1].Value.Pipe(WebUtility.UrlDecode); if (!string.IsNullOrWhiteSpace(text) && IsValid(text)) { return text; } string text2 = Regex.Match(playlistIdOrUrl, "youtube\\..+?/watch.*?list=(.*?)(?:&|/|$)").Groups[1].Value.Pipe(WebUtility.UrlDecode); if (!string.IsNullOrWhiteSpace(text2) && IsValid(text2)) { return text2; } string text3 = Regex.Match(playlistIdOrUrl, "youtu\\.be/.*?/.*?list=(.*?)(?:&|/|$)").Groups[1].Value.Pipe(WebUtility.UrlDecode); if (!string.IsNullOrWhiteSpace(text3) && IsValid(text3)) { return text3; } string text4 = Regex.Match(playlistIdOrUrl, "youtube\\..+?/embed/.*?/.*?list=(.*?)(?:&|/|$)").Groups[1].Value.Pipe(WebUtility.UrlDecode); if (!string.IsNullOrWhiteSpace(text4) && IsValid(text4)) { return text4; } return null; } public static PlaylistId? TryParse(string? playlistIdOrUrl) { return TryNormalize(playlistIdOrUrl)?.Pipe((string id) => new PlaylistId(id)); } public static PlaylistId Parse(string playlistIdOrUrl) { return TryParse(playlistIdOrUrl) ?? throw new ArgumentException("Invalid YouTube playlist ID or URL '" + playlistIdOrUrl + "'."); } public static implicit operator PlaylistId(string playlistIdOrUrl) { return Parse(playlistIdOrUrl); } public static implicit operator string(PlaylistId playlistId) { return playlistId.ToString(); } public bool Equals(PlaylistId other) { return StringComparer.Ordinal.Equals(Value, other.Value); } public override bool Equals(object? obj) { return obj is PlaylistId other && Equals(other); } public override int GetHashCode() { return StringComparer.Ordinal.GetHashCode(Value); } public static bool operator ==(PlaylistId left, PlaylistId right) { return left.Equals(right); } public static bool operator !=(PlaylistId left, PlaylistId right) { return !(left == right); } } public class PlaylistVideo : IVideo, IBatchItem { public PlaylistId Pla