From b5c701b9710607d0422d0877134f33d6a54e9c9b Mon Sep 17 00:00:00 2001 From: max Date: Fri, 24 Oct 2025 21:16:08 +0200 Subject: [PATCH] [CHANGE] Reworked cipher stuff --- .../Application/Dev/CipherDev.razor | 13 ++++++ .../Application/Dev/CipherDev.razor.cs | 43 +++++++++++++++++++ .../Application/Dev/DevelopmentVideo.razor | 2 +- .../Components/Pages/Development.razor | 3 ++ Manager.App/Services/LibraryService.cs | 4 +- .../Models/Innertube/StreamingData.cs | 2 + Manager.YouTube/Util/Cipher/CipherDecoder.cs | 2 +- .../Util/Converters/JsonUrlEscapeConverter.cs | 27 ++++++++++++ 8 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 Manager.App/Components/Application/Dev/CipherDev.razor create mode 100644 Manager.App/Components/Application/Dev/CipherDev.razor.cs create mode 100644 Manager.YouTube/Util/Converters/JsonUrlEscapeConverter.cs diff --git a/Manager.App/Components/Application/Dev/CipherDev.razor b/Manager.App/Components/Application/Dev/CipherDev.razor new file mode 100644 index 0000000..42d9609 --- /dev/null +++ b/Manager.App/Components/Application/Dev/CipherDev.razor @@ -0,0 +1,13 @@ +@using Manager.App.Models.System +@using Manager.App.Services.System + +@inject ISnackbar Snackbar +@inject ClientService ClientService + +Cipher manager + + + + Exec + \ No newline at end of file diff --git a/Manager.App/Components/Application/Dev/CipherDev.razor.cs b/Manager.App/Components/Application/Dev/CipherDev.razor.cs new file mode 100644 index 0000000..dd7d7a9 --- /dev/null +++ b/Manager.App/Components/Application/Dev/CipherDev.razor.cs @@ -0,0 +1,43 @@ +using Manager.App.Models.System; +using Manager.YouTube.Util.Cipher; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudBlazor; + +namespace Manager.App.Components.Application.Dev; + +public partial class CipherDev : ComponentBase +{ + private YouTubeClientItem? _selectedClient; + + private async Task ExecCipher(MouseEventArgs obj) + { + if (_selectedClient == null) + { + Snackbar.Add("No client selected", Severity.Warning); + return; + } + + var ytClientResult = await ClientService.LoadClientByIdAsync(_selectedClient.Id); + if (!ytClientResult.IsSuccess) + { + Snackbar.Add(ytClientResult.Error?.Description ?? "Failed to get the client!", Severity.Error); + return; + } + + var ytClient = ytClientResult.Value; + if (ytClient.State == null) + { + Snackbar.Add("Client state is null!", Severity.Warning); + return; + } + + var decoder = await CipherManager.GetDecoderAsync(ytClient.State, ytClient); + } + + private async Task> SearchClientsAsync(string? search, CancellationToken cancellationToken) + { + var searchResults = await ClientService.GetClientsAsync(search, cancellationToken: cancellationToken); + return !searchResults.IsSuccess ? [] : searchResults.Value; + } +} \ No newline at end of file diff --git a/Manager.App/Components/Application/Dev/DevelopmentVideo.razor b/Manager.App/Components/Application/Dev/DevelopmentVideo.razor index bd8c941..1495d71 100644 --- a/Manager.App/Components/Application/Dev/DevelopmentVideo.razor +++ b/Manager.App/Components/Application/Dev/DevelopmentVideo.razor @@ -5,7 +5,7 @@ @inject ClientService ClientService Video data - + diff --git a/Manager.App/Components/Pages/Development.razor b/Manager.App/Components/Pages/Development.razor index 2a3a512..bc2da8f 100644 --- a/Manager.App/Components/Pages/Development.razor +++ b/Manager.App/Components/Pages/Development.razor @@ -9,4 +9,7 @@ + + + \ No newline at end of file diff --git a/Manager.App/Services/LibraryService.cs b/Manager.App/Services/LibraryService.cs index 0e3ef22..3f7fa02 100644 --- a/Manager.App/Services/LibraryService.cs +++ b/Manager.App/Services/LibraryService.cs @@ -144,9 +144,9 @@ public class LibraryService : ILibraryService try { await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken); - var channel = await context.Channels + var channel = await context.Channels.AsSplitQuery() .Include(c => c.ClientAccount) - .ThenInclude(p => p!.HttpCookies) + .ThenInclude(p => p!.HttpCookies) .Include(f => f.Files) .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); diff --git a/Manager.YouTube/Models/Innertube/StreamingData.cs b/Manager.YouTube/Models/Innertube/StreamingData.cs index 56947d0..4f39c6b 100644 --- a/Manager.YouTube/Models/Innertube/StreamingData.cs +++ b/Manager.YouTube/Models/Innertube/StreamingData.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using Manager.YouTube.Util.Converters; namespace Manager.YouTube.Models.Innertube; @@ -8,6 +9,7 @@ public class StreamingData [JsonPropertyName("expiresInSeconds")] public int ExpiresInSeconds { get; set; } [JsonPropertyName("serverAbrStreamingUrl")] + [JsonConverter(typeof(JsonUrlEscapeConverter))] public string ServerAbrStreamingUrl { get; set; } = ""; [JsonPropertyName("formats")] public List Formats { get; set; } = []; diff --git a/Manager.YouTube/Util/Cipher/CipherDecoder.cs b/Manager.YouTube/Util/Cipher/CipherDecoder.cs index b9c0663..9f43ae2 100644 --- a/Manager.YouTube/Util/Cipher/CipherDecoder.cs +++ b/Manager.YouTube/Util/Cipher/CipherDecoder.cs @@ -112,7 +112,7 @@ public partial class CipherDecoder } - [GeneratedRegex(@"(\w+)=function\(\w+\){(\w+)=\2\.split\(\x22{2}\);.*?return\s+\2\.join\(\x22{2}\)}")] + [GeneratedRegex(@"([A-Za-z_$][A-Za-z0-9_$]*)=function\([A-Za-z_$][A-Za-z0-9_$]*\)\{\s*([A-Za-z_$][A-Za-z0-9_$]*)=\2\.split\(\x22\x22\);[\s\S]*?return\s+\2\.join\(\x22\x22\)\s*\}")] private static partial Regex FunctionBodyRegex(); [GeneratedRegex("([\\$_\\w]+).\\w+\\(\\w+,\\d+\\);")] private static partial Regex DefinitionBodyRegex(); diff --git a/Manager.YouTube/Util/Converters/JsonUrlEscapeConverter.cs b/Manager.YouTube/Util/Converters/JsonUrlEscapeConverter.cs new file mode 100644 index 0000000..f5efd32 --- /dev/null +++ b/Manager.YouTube/Util/Converters/JsonUrlEscapeConverter.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; + +namespace Manager.YouTube.Util.Converters; + +public partial class JsonUrlEscapeConverter : JsonConverter +{ + public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var url = reader.GetString(); + if (string.IsNullOrWhiteSpace(url)) + { + return url; + } + + return UrlPatternRegex().IsMatch(url) ? Uri.UnescapeDataString(url) : url; + } + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + { + writer.WriteStringValue(value); + } + + [GeneratedRegex("^(https?|ftp)://", RegexOptions.IgnoreCase | RegexOptions.Compiled, "nl-NL")] + private static partial Regex UrlPatternRegex(); +} \ No newline at end of file