From d3829323eb6ff2761b3d92671b7a612ea22acb4a Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Tue, 13 Jan 2026 10:09:13 +0200 Subject: [PATCH 01/15] docs: add donation section to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5b6002f..3df6fdf 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,7 @@ modules - optional, if not specified, all modules from the repository will be in "displayindex": 1 } ``` + +## Donate + +Support the author: https://lampame.donatik.me From 838dc96aa9ef2c3b61ae43582d4fede0f4421cfe Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 08:47:38 +0200 Subject: [PATCH 02/15] refactor(uakino): replace Http.Get with custom GetString method Implement a new GetString method using HttpClient for better control over HTTP requests including proxy handling, SSL validation, and timeout management. This replaces the previous Http.Get calls throughout the UAKino module to standardize request handling and improve reliability. --- UAKino/UAKinoInvoke.cs | 51 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index 03bd315..be6e528 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -1,8 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Authentication; using System.Text.Json; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using System.Web; using HtmlAgilityPack; @@ -62,7 +66,7 @@ namespace UAKino }; _onLog?.Invoke($"UAKino search: {searchUrl}"); - string html = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); + string html = await GetString(searchUrl, headers); if (string.IsNullOrEmpty(html)) continue; @@ -147,7 +151,7 @@ namespace UAKino try { _onLog?.Invoke($"UAKino playlist: {url}"); - string payload = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); + string payload = await GetString(url, headers); if (string.IsNullOrEmpty(payload)) return null; @@ -189,7 +193,7 @@ namespace UAKino try { _onLog?.Invoke($"UAKino movie page: {href}"); - string html = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); + string html = await GetString(href, headers); if (string.IsNullOrEmpty(html)) return null; @@ -232,7 +236,7 @@ namespace UAKino try { _onLog?.Invoke($"UAKino parse player: {url}"); - string html = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); + string html = await GetString(url, headers); if (string.IsNullOrEmpty(html)) return null; @@ -253,6 +257,45 @@ namespace UAKino } } + private async Task GetString(string url, List headers, int timeoutSeconds = 15) + { + var handler = new HttpClientHandler + { + AllowAutoRedirect = true, + AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip | DecompressionMethods.Deflate, + SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 + }; + + handler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; + + var proxy = _proxyManager.Get(); + if (proxy != null) + { + handler.UseProxy = true; + handler.Proxy = proxy; + } + else + { + handler.UseProxy = false; + } + + using var client = new HttpClient(handler); + using var req = new HttpRequestMessage(HttpMethod.Get, url); + + if (headers != null) + { + foreach (var h in headers) + req.Headers.TryAddWithoutValidation(h.name, h.val); + } + + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(Math.Max(5, timeoutSeconds))); + using var response = await client.SendAsync(req, cts.Token).ConfigureAwait(false); + if (!response.IsSuccessStatusCode) + return null; + + return await response.Content.ReadAsStringAsync(cts.Token).ConfigureAwait(false); + } + private List ParsePlaylistHtml(string html) { var items = new List(); From 768c916b1d6f29ee53c0de6e1d5937a7371410d4 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:01:01 +0200 Subject: [PATCH 03/15] feat(api): add streamlink parameter to call method The change adds a new 'streamlink' parameter to the call method in the Controller to support direct playback functionality. This enhances the API by providing a dedicated endpoint for streaming content with play=true query parameter. --- Uaflix/Controller.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Uaflix/Controller.cs b/Uaflix/Controller.cs index fb73002..edb0e49 100644 --- a/Uaflix/Controller.cs +++ b/Uaflix/Controller.cs @@ -282,7 +282,8 @@ namespace Uaflix.Controllers s: s.ToString(), e: ep.Number.ToString(), link: accsArgs(callUrl), - method: "call" + method: "call", + streamlink: accsArgs($"{callUrl}&play=true") ); } else @@ -331,4 +332,3 @@ namespace Uaflix.Controllers } } - From 60d7b15dc1bb50201f8988f3265bd7e62985f9f0 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:18:51 +0200 Subject: [PATCH 04/15] feat(uaflix): normalize voice names in aggregated structure Add NormalizeUaflixVoiceNames method to standardize voice naming by converting "Uaflix #2" or "Uaflix #3" to "Uaflix" when base name is missing. This ensures consistent voice naming across the system. The method checks for existing voice keys and renames them appropriately to maintain a single canonical voice name. --- Uaflix/UaflixInvoke.cs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Uaflix/UaflixInvoke.cs b/Uaflix/UaflixInvoke.cs index cd65b65..03c16bd 100644 --- a/Uaflix/UaflixInvoke.cs +++ b/Uaflix/UaflixInvoke.cs @@ -500,6 +500,8 @@ namespace Uaflix return null; } + NormalizeUaflixVoiceNames(structure); + // Edge Case 9: Перевірка наявності епізодів у озвучках bool hasEpisodes = structure.Voices.Values.Any(v => v.Seasons.Values.Any(s => s.Any())); if (!hasEpisodes) @@ -888,6 +890,38 @@ namespace Uaflix return result; } + private void NormalizeUaflixVoiceNames(SerialAggregatedStructure structure) + { + const string baseName = "Uaflix"; + const string zetName = "Uaflix #2"; + const string ashdiName = "Uaflix #3"; + + if (structure == null || structure.Voices == null || structure.Voices.Count == 0) + return; + + bool hasBase = structure.Voices.ContainsKey(baseName); + bool hasZet = structure.Voices.ContainsKey(zetName); + bool hasAshdi = structure.Voices.ContainsKey(ashdiName); + + if (hasBase) + return; + + if (hasZet && !hasAshdi) + { + var voice = structure.Voices[zetName]; + voice.DisplayName = baseName; + structure.Voices.Remove(zetName); + structure.Voices[baseName] = voice; + } + else if (hasAshdi && !hasZet) + { + var voice = structure.Voices[ashdiName]; + voice.DisplayName = baseName; + structure.Voices.Remove(ashdiName); + structure.Voices[baseName] = voice; + } + } + async Task> ParseAllZetvideoSources(string iframeUrl) { var result = new List<(string link, string quality)>(); @@ -985,4 +1019,4 @@ namespace Uaflix return TimeSpan.FromMinutes(ctime); } } -} \ No newline at end of file +} From 58bb8d194c1a318ad677778de22824bf0e2c9f66 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:31:09 +0200 Subject: [PATCH 05/15] feat(starlight): add episode image support and improve image selection - Add Image property to Episode model - Update episode template call to include image parameter - Implement SelectImage helper method for flexible image source selection - Enhance image selection logic for both main content and episodes --- StarLight/Controller.cs | 2 +- StarLight/Models/StarLightModels.cs | 1 + StarLight/StarLightInvoke.cs | 20 ++++++++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/StarLight/Controller.cs b/StarLight/Controller.cs index 7e1ce59..31d0e7b 100644 --- a/StarLight/Controller.cs +++ b/StarLight/Controller.cs @@ -89,7 +89,7 @@ namespace StarLight.Controllers string episodeName = string.IsNullOrEmpty(ep.Title) ? $"Епізод {index}" : ep.Title; string callUrl = $"{host}/starlight/play?hash={HttpUtility.UrlEncode(ep.Hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}"; - episode_tpl.Append(episodeName, title ?? original_title, (s + 1).ToString(), index.ToString("D2"), accsArgs(callUrl), "call"); + episode_tpl.Append(episodeName, title ?? original_title, (s + 1).ToString(), index.ToString("D2"), accsArgs(callUrl), "call", img: ep.Image); index++; } diff --git a/StarLight/Models/StarLightModels.cs b/StarLight/Models/StarLightModels.cs index 90142aa..43d416b 100644 --- a/StarLight/Models/StarLightModels.cs +++ b/StarLight/Models/StarLightModels.cs @@ -24,6 +24,7 @@ namespace StarLight.Models public string VideoSlug { get; set; } public string Date { get; set; } public string SeasonSlug { get; set; } + public string Image { get; set; } } public class ProjectInfo diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index 771d853..002c81d 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -119,7 +119,7 @@ namespace StarLight { Title = root.TryGetProperty("title", out var titleProp) ? titleProp.GetString() : null, Description = root.TryGetProperty("description", out var descProp) ? descProp.GetString() : null, - Poster = NormalizeImage(root.TryGetProperty("image", out var imageProp) ? imageProp.GetString() : null), + Poster = NormalizeImage(SelectImage(root, "imageMob", "imageTab", "image", "logoImage")), Hash = root.TryGetProperty("hash", out var hashProp) ? hashProp.GetString() : null, Type = root.TryGetProperty("typeSlug", out var typeProp) ? typeProp.GetString() : null, Channel = root.TryGetProperty("channelTitle", out var channelProp) ? channelProp.GetString() : null @@ -143,7 +143,8 @@ namespace StarLight Hash = item.TryGetProperty("hash", out var eHash) ? eHash.GetString() : null, VideoSlug = item.TryGetProperty("videoSlug", out var eSlug) ? eSlug.GetString() : null, Date = item.TryGetProperty("dateOfBroadcast", out var eDate) ? eDate.GetString() : (item.TryGetProperty("timeUploadVideo", out var eDate2) ? eDate2.GetString() : null), - SeasonSlug = seasonSlug + SeasonSlug = seasonSlug, + Image = NormalizeImage(SelectImage(item, "imageMob", "image")) }); } } @@ -240,6 +241,21 @@ namespace StarLight return $"{_init.host}{path}"; } + private static string SelectImage(JsonElement element, params string[] keys) + { + foreach (var key in keys) + { + if (element.TryGetProperty(key, out var prop)) + { + var value = prop.GetString(); + if (!string.IsNullOrEmpty(value)) + return value; + } + } + + return null; + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) From 90fe957674cc213d4450e1caeb273f1ec2bb4b52 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:39:18 +0200 Subject: [PATCH 06/15] feat(starlight): refactor episode handling to use structured JSON data - Replace EpisodeTpl with a new structured approach using List<(string name, object json)> - Add BuildEpisodeJson and BuildEpisodeHtml methods for consistent output generation - Implement proper JSON serialization with null value handling - Add language check in OnlineApi to only process Ukrainian content - Improve episode display with better title formatting and image handling --- StarLight/Controller.cs | 77 +++++++++++++++++++++++++++++++++++++++-- StarLight/OnlineApi.cs | 4 +++ 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/StarLight/Controller.cs b/StarLight/Controller.cs index 31d0e7b..28461c8 100644 --- a/StarLight/Controller.cs +++ b/StarLight/Controller.cs @@ -1,5 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Web; using Microsoft.AspNetCore.Mvc; @@ -80,7 +84,7 @@ namespace StarLight.Controllers if (episodes == null || episodes.Count == 0) return OnError("starlight", proxyManager); - var episode_tpl = new EpisodeTpl(); + var episodeItems = new List<(string name, object json)>(); int index = 1; foreach (var ep in episodes) { @@ -89,11 +93,30 @@ namespace StarLight.Controllers string episodeName = string.IsNullOrEmpty(ep.Title) ? $"Епізод {index}" : ep.Title; string callUrl = $"{host}/starlight/play?hash={HttpUtility.UrlEncode(ep.Hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}"; - episode_tpl.Append(episodeName, title ?? original_title, (s + 1).ToString(), index.ToString("D2"), accsArgs(callUrl), "call", img: ep.Image); + string image = string.IsNullOrEmpty(ep.Image) ? null : ep.Image; + string displayTitle = $"{title ?? original_title} ({index} серия)"; + + var jsonItem = new + { + method = "call", + url = accsArgs(callUrl), + s = (short)(s + 1), + e = (short)index, + name = episodeName, + title = displayTitle, + img = image + }; + + episodeItems.Add((episodeName, jsonItem)); index++; } - return rjson ? Content(episode_tpl.ToJson(), "application/json; charset=utf-8") : Content(episode_tpl.ToHtml(), "text/html; charset=utf-8"); + if (episodeItems.Count == 0) + return OnError("starlight", proxyManager); + + return rjson + ? Content(BuildEpisodeJson(episodeItems.Select(i => i.json)), "application/json; charset=utf-8") + : Content(BuildEpisodeHtml(episodeItems), "text/html; charset=utf-8"); } else { @@ -132,5 +155,53 @@ namespace StarLight.Controllers string jsonResult = $"{{\"method\":\"play\",\"url\":\"{streamUrl}\",\"title\":\"{title ?? result.Name ?? ""}\"}}"; return Content(jsonResult, "application/json; charset=utf-8"); } + + private static readonly JsonSerializerOptions EpisodeJsonOptions = new JsonSerializerOptions + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; + + private static string BuildEpisodeJson(IEnumerable items) + { + var payload = new + { + type = "episode", + data = items + }; + + return JsonSerializer.Serialize(payload, EpisodeJsonOptions); + } + + private static string BuildEpisodeHtml(List<(string name, object json)> items) + { + var html = new StringBuilder(); + bool firstjson = true; + + html.Append("
"); + + foreach (var item in items) + { + html.Append("
"); + + html.Append("
"); + UtilsTpl.HtmlEncode(item.name, html); + html.Append("
"); + + firstjson = false; + } + + html.Append("
"); + + return html.ToString(); + } } } diff --git a/StarLight/OnlineApi.cs b/StarLight/OnlineApi.cs index ce3b4c3..20bb35b 100644 --- a/StarLight/OnlineApi.cs +++ b/StarLight/OnlineApi.cs @@ -1,4 +1,5 @@ using Shared.Models.Base; +using System; using System.Collections.Generic; namespace StarLight @@ -9,6 +10,9 @@ namespace StarLight { var online = new List<(string name, string url, string plugin, int index)>(); + if (!string.Equals(original_language, "uk", StringComparison.OrdinalIgnoreCase)) + return online; + var init = ModInit.StarLight; if (init.enable && !init.rip) { From 0d029f362d90b947b6fda82d55cb09976f6c3dcc Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:40:45 +0200 Subject: [PATCH 07/15] refactor(starlight): update namespace reference for HtmlEncode utility The change updates the UtilsTpl.HtmlEncode call to use the fully qualified namespace Shared.Models.Templates.UtilsTpl.HtmlEncode for consistency with the project's namespace structure and to avoid potential ambiguity --- StarLight/Controller.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StarLight/Controller.cs b/StarLight/Controller.cs index 28461c8..58ee1cd 100644 --- a/StarLight/Controller.cs +++ b/StarLight/Controller.cs @@ -193,7 +193,7 @@ namespace StarLight.Controllers html.Append("'>"); html.Append("
"); - UtilsTpl.HtmlEncode(item.name, html); + Shared.Models.Templates.UtilsTpl.HtmlEncode(item.name, html); html.Append("
"); firstjson = false; From f32b2b2cc2df11f0daf783f30c83f1fbec07cdf2 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:42:48 +0200 Subject: [PATCH 08/15] refactor(starlight): replace external HtmlEncode with local implementation The Controller.cs file now uses a local HtmlEncode method instead of the external Shared.Models.Templates.UtilsTpl.HtmlEncode utility. This change improves encapsulation and reduces external dependencies while maintaining the same HTML encoding functionality for special characters. --- StarLight/Controller.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/StarLight/Controller.cs b/StarLight/Controller.cs index 58ee1cd..efa9acf 100644 --- a/StarLight/Controller.cs +++ b/StarLight/Controller.cs @@ -193,7 +193,7 @@ namespace StarLight.Controllers html.Append("'>"); html.Append("
"); - Shared.Models.Templates.UtilsTpl.HtmlEncode(item.name, html); + HtmlEncode(item.name, html); html.Append("
"); firstjson = false; @@ -203,5 +203,24 @@ namespace StarLight.Controllers return html.ToString(); } + + private static void HtmlEncode(string value, StringBuilder sb) + { + if (string.IsNullOrEmpty(value)) + return; + + foreach (var c in value) + { + switch (c) + { + case '<': sb.Append("<"); break; + case '>': sb.Append(">"); break; + case '&': sb.Append("&"); break; + case '"': sb.Append("""); break; + case '\'': sb.Append("'"); break; + default: sb.Append(c); break; + } + } + } } } From b7cd641da6ea5011d5264541160cff4625ac0de9 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 09:47:29 +0200 Subject: [PATCH 09/15] feat(starlight): add episode image support to episode items - Extend episode item tuple to include image field - Update BuildEpisodeHtml to render episode images when available - Maintain backward compatibility for episodes without images --- StarLight/Controller.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/StarLight/Controller.cs b/StarLight/Controller.cs index efa9acf..4c2d352 100644 --- a/StarLight/Controller.cs +++ b/StarLight/Controller.cs @@ -84,7 +84,7 @@ namespace StarLight.Controllers if (episodes == null || episodes.Count == 0) return OnError("starlight", proxyManager); - var episodeItems = new List<(string name, object json)>(); + var episodeItems = new List<(string name, object json, string image)>(); int index = 1; foreach (var ep in episodes) { @@ -107,7 +107,7 @@ namespace StarLight.Controllers img = image }; - episodeItems.Add((episodeName, jsonItem)); + episodeItems.Add((episodeName, jsonItem, image)); index++; } @@ -172,7 +172,7 @@ namespace StarLight.Controllers return JsonSerializer.Serialize(payload, EpisodeJsonOptions); } - private static string BuildEpisodeHtml(List<(string name, object json)> items) + private static string BuildEpisodeHtml(List<(string name, object json, string image)> items) { var html = new StringBuilder(); bool firstjson = true; @@ -192,7 +192,18 @@ namespace StarLight.Controllers html.Append(JsonSerializer.Serialize(item.json, EpisodeJsonOptions)); html.Append("'>"); - html.Append("
"); + if (!string.IsNullOrEmpty(item.image)) + { + html.Append("
"); + } + else + { + html.Append("
"); + } + + html.Append("
"); HtmlEncode(item.name, html); html.Append("
"); From 1525e163dd717c69c4dc2b31b7f9ffcf8bf87779 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 10:03:13 +0200 Subject: [PATCH 10/15] refactor(starlight): simplify episode handling using EpisodeTpl class - Remove manual JSON and HTML building logic in Controller.cs - Eliminate unused image handling and selection logic - Remove redundant JsonSerializerOptions and helper methods - Update Episode model to remove Image property - Simplify image selection in StarLightInvoke.cs to use single source --- StarLight/Controller.cs | 105 +--------------------------- StarLight/Models/StarLightModels.cs | 1 - StarLight/StarLightInvoke.cs | 19 +---- 3 files changed, 5 insertions(+), 120 deletions(-) diff --git a/StarLight/Controller.cs b/StarLight/Controller.cs index 4c2d352..7e449b5 100644 --- a/StarLight/Controller.cs +++ b/StarLight/Controller.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Web; using Microsoft.AspNetCore.Mvc; @@ -84,7 +81,7 @@ namespace StarLight.Controllers if (episodes == null || episodes.Count == 0) return OnError("starlight", proxyManager); - var episodeItems = new List<(string name, object json, string image)>(); + var episode_tpl = new EpisodeTpl(); int index = 1; foreach (var ep in episodes) { @@ -93,30 +90,11 @@ namespace StarLight.Controllers string episodeName = string.IsNullOrEmpty(ep.Title) ? $"Епізод {index}" : ep.Title; string callUrl = $"{host}/starlight/play?hash={HttpUtility.UrlEncode(ep.Hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}"; - string image = string.IsNullOrEmpty(ep.Image) ? null : ep.Image; - string displayTitle = $"{title ?? original_title} ({index} серия)"; - - var jsonItem = new - { - method = "call", - url = accsArgs(callUrl), - s = (short)(s + 1), - e = (short)index, - name = episodeName, - title = displayTitle, - img = image - }; - - episodeItems.Add((episodeName, jsonItem, image)); + episode_tpl.Append(episodeName, title ?? original_title, (s + 1).ToString(), index.ToString("D2"), accsArgs(callUrl), "call"); index++; } - if (episodeItems.Count == 0) - return OnError("starlight", proxyManager); - - return rjson - ? Content(BuildEpisodeJson(episodeItems.Select(i => i.json)), "application/json; charset=utf-8") - : Content(BuildEpisodeHtml(episodeItems), "text/html; charset=utf-8"); + return rjson ? Content(episode_tpl.ToJson(), "application/json; charset=utf-8") : Content(episode_tpl.ToHtml(), "text/html; charset=utf-8"); } else { @@ -156,82 +134,5 @@ namespace StarLight.Controllers return Content(jsonResult, "application/json; charset=utf-8"); } - private static readonly JsonSerializerOptions EpisodeJsonOptions = new JsonSerializerOptions - { - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }; - - private static string BuildEpisodeJson(IEnumerable items) - { - var payload = new - { - type = "episode", - data = items - }; - - return JsonSerializer.Serialize(payload, EpisodeJsonOptions); - } - - private static string BuildEpisodeHtml(List<(string name, object json, string image)> items) - { - var html = new StringBuilder(); - bool firstjson = true; - - html.Append("
"); - - foreach (var item in items) - { - html.Append("
"); - - if (!string.IsNullOrEmpty(item.image)) - { - html.Append("
"); - } - else - { - html.Append("
"); - } - - html.Append("
"); - HtmlEncode(item.name, html); - html.Append("
"); - - firstjson = false; - } - - html.Append("
"); - - return html.ToString(); - } - - private static void HtmlEncode(string value, StringBuilder sb) - { - if (string.IsNullOrEmpty(value)) - return; - - foreach (var c in value) - { - switch (c) - { - case '<': sb.Append("<"); break; - case '>': sb.Append(">"); break; - case '&': sb.Append("&"); break; - case '"': sb.Append("""); break; - case '\'': sb.Append("'"); break; - default: sb.Append(c); break; - } - } - } } } diff --git a/StarLight/Models/StarLightModels.cs b/StarLight/Models/StarLightModels.cs index 43d416b..90142aa 100644 --- a/StarLight/Models/StarLightModels.cs +++ b/StarLight/Models/StarLightModels.cs @@ -24,7 +24,6 @@ namespace StarLight.Models public string VideoSlug { get; set; } public string Date { get; set; } public string SeasonSlug { get; set; } - public string Image { get; set; } } public class ProjectInfo diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index 002c81d..11c8bb6 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -119,7 +119,7 @@ namespace StarLight { Title = root.TryGetProperty("title", out var titleProp) ? titleProp.GetString() : null, Description = root.TryGetProperty("description", out var descProp) ? descProp.GetString() : null, - Poster = NormalizeImage(SelectImage(root, "imageMob", "imageTab", "image", "logoImage")), + Poster = NormalizeImage(root.TryGetProperty("image", out var imageProp) ? imageProp.GetString() : null), Hash = root.TryGetProperty("hash", out var hashProp) ? hashProp.GetString() : null, Type = root.TryGetProperty("typeSlug", out var typeProp) ? typeProp.GetString() : null, Channel = root.TryGetProperty("channelTitle", out var channelProp) ? channelProp.GetString() : null @@ -143,8 +143,7 @@ namespace StarLight Hash = item.TryGetProperty("hash", out var eHash) ? eHash.GetString() : null, VideoSlug = item.TryGetProperty("videoSlug", out var eSlug) ? eSlug.GetString() : null, Date = item.TryGetProperty("dateOfBroadcast", out var eDate) ? eDate.GetString() : (item.TryGetProperty("timeUploadVideo", out var eDate2) ? eDate2.GetString() : null), - SeasonSlug = seasonSlug, - Image = NormalizeImage(SelectImage(item, "imageMob", "image")) + SeasonSlug = seasonSlug }); } } @@ -241,20 +240,6 @@ namespace StarLight return $"{_init.host}{path}"; } - private static string SelectImage(JsonElement element, params string[] keys) - { - foreach (var key in keys) - { - if (element.TryGetProperty(key, out var prop)) - { - var value = prop.GetString(); - if (!string.IsNullOrEmpty(value)) - return value; - } - } - - return null; - } public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { From 0c06d065d5b8f87786b45fd00bb553721787d3cc Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 12:58:57 +0200 Subject: [PATCH 11/15] refactor(http): migrate from HttpClientHandler to SocketsHttpHandler Update SSL certificate validation approach to use SslClientAuthenticationOptions with a custom validation callback. This modernizes the HTTP client implementation while maintaining the same security behavior of accepting all certificates. BREAKING CHANGE: The underlying HTTP handler implementation has changed from HttpClientHandler to SocketsHttpHandler, which may affect behavior in edge cases --- UAKino/UAKinoInvoke.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index be6e528..a4c3b82 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Security; using System.Security.Authentication; using System.Text.Json; using System.Text.RegularExpressions; @@ -259,15 +260,17 @@ namespace UAKino private async Task GetString(string url, List headers, int timeoutSeconds = 15) { - var handler = new HttpClientHandler + var handler = new SocketsHttpHandler { AllowAutoRedirect = true, AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip | DecompressionMethods.Deflate, - SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 + SslOptions = new SslClientAuthenticationOptions + { + RemoteCertificateValidationCallback = (_, _, _, _) => true, + EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 + } }; - handler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; - var proxy = _proxyManager.Get(); if (proxy != null) { From 6041ea950b0cf0fda0cbe56ef7c69886da64200d Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 13:21:34 +0200 Subject: [PATCH 12/15] feat(security): add host blocking mechanism across all online services Adds a comprehensive host blocking system that prevents requests to specific disallowed hosts across all online streaming services. The implementation includes: - New `NotAllowedHosts` HashSet containing base64-encoded blocked hostnames - `IsNotAllowedHost()` method to validate URLs before making HTTP requests - Integration in all service classes (Anihub, AnimeON, Bamboo, CikavaIdeya, StarLight, UAKino, UaTUT, Uaflix, Unimay) - Checks applied to search, content fetching, and streaming URL resolution - Consistent implementation pattern across both Invoke and Controller classes This security enhancement prevents connections to potentially malicious or unauthorized streaming hosts while maintaining existing functionality for allowed sources. --- Anihub/AnihubInvoke.cs | 28 ++++++++++++++ Anihub/Controller.cs | 26 +++++++++++++ AnimeON/AnimeONInvoke.cs | 44 +++++++++++++++++++++ AnimeON/Controller.cs | 32 ++++++++++++++++ Bamboo/BambooInvoke.cs | 38 +++++++++++++++++-- CikavaIdeya/CikavaIdeyaInvoke.cs | 37 +++++++++++++++++- CikavaIdeya/Controller.cs | 34 ++++++++++++++++- StarLight/StarLightInvoke.cs | 35 ++++++++++++++++- UAKino/UAKinoInvoke.cs | 32 ++++++++++++++-- UaTUT/UaTUTInvoke.cs | 32 ++++++++++++++++ Uaflix/Controller.cs | 27 ++++++++++++- Uaflix/UaflixInvoke.cs | 65 +++++++++++++++++++++++++++++++- Unimay/UnimayInvoke.cs | 32 +++++++++++++++- 13 files changed, 448 insertions(+), 14 deletions(-) diff --git a/Anihub/AnihubInvoke.cs b/Anihub/AnihubInvoke.cs index 91548ec..c53fbaa 100644 --- a/Anihub/AnihubInvoke.cs +++ b/Anihub/AnihubInvoke.cs @@ -19,6 +19,17 @@ namespace Anihub { public class AnihubInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -41,6 +52,9 @@ namespace Anihub string searchQuery = string.IsNullOrEmpty(title) ? original_title : title; string searchUrl = $"{_init.apihost}/anime/?search={HttpUtility.UrlEncode(searchQuery)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + string response = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(response)) @@ -75,6 +89,9 @@ namespace Anihub ); string sourcesUrl = $"{_init.apihost}/episode-sources/{parsedAnimeId}"; + if (IsNotAllowedHost(sourcesUrl)) + return null; + string response = await Http.Get(sourcesUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(response)) @@ -156,6 +173,17 @@ namespace Anihub return voices; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public async Task> GetSeasons(AnihubEpisodeSourcesResponse sources) { var seasons = new List(); diff --git a/Anihub/Controller.cs b/Anihub/Controller.cs index bb3eef2..d81fe95 100644 --- a/Anihub/Controller.cs +++ b/Anihub/Controller.cs @@ -13,12 +13,24 @@ using Shared.Models.Online.Settings; using Shared.Models; using System.Net; using System.Net.Http; +using System.Text; namespace Anihub { [Route("anihub")] public class AnihubController : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public AnihubController() @@ -299,6 +311,9 @@ namespace Anihub requestUrl = iframeUrl + (iframeUrl.Contains("?") ? "&" : "?") + $"player={host}"; } + if (IsNotAllowedHost(requestUrl)) + return null; + // Створюємо HTTP клієнт з правильними заголовками using var httpClient = new HttpClient(); @@ -349,5 +364,16 @@ namespace Anihub return null; } } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } } diff --git a/AnimeON/AnimeONInvoke.cs b/AnimeON/AnimeONInvoke.cs index f268c43..48d124e 100644 --- a/AnimeON/AnimeONInvoke.cs +++ b/AnimeON/AnimeONInvoke.cs @@ -6,6 +6,7 @@ using Shared.Models.Online.Settings; using Shared.Models; using System.Text.Json; using System.Linq; +using System.Text; using AnimeON.Models; using Shared.Engine; @@ -13,6 +14,17 @@ namespace AnimeON { public class AnimeONInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -42,6 +54,9 @@ namespace AnimeON return null; string searchUrl = $"{_init.host}/api/anime/search?text={System.Web.HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {searchUrl}"); string searchJson = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(searchJson)) @@ -87,6 +102,9 @@ namespace AnimeON public async Task> GetFundubs(int animeId) { string fundubsUrl = $"{_init.host}/api/player/{animeId}/translations"; + if (IsNotAllowedHost(fundubsUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {fundubsUrl}"); string fundubsJson = await Http.Get(fundubsUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(fundubsJson)) @@ -112,6 +130,9 @@ namespace AnimeON public async Task GetEpisodes(int animeId, int playerId, int fundubId) { string episodesUrl = $"{_init.host}/api/player/{animeId}/episodes?take=100&skip=-1&playerId={playerId}&translationId={fundubId}"; + if (IsNotAllowedHost(episodesUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {episodesUrl}"); string episodesJson = await Http.Get(episodesUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(episodesJson)) @@ -131,6 +152,9 @@ namespace AnimeON new HeadersModel("Referer", "https://animeon.club/") }; + if (IsNotAllowedHost(requestUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {requestUrl}"); string html = await Http.Get(requestUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -160,6 +184,9 @@ namespace AnimeON new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(url)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {url}"); string html = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -184,6 +211,9 @@ namespace AnimeON try { string url = $"{_init.host}/api/player/{episodeId}/episode"; + if (IsNotAllowedHost(url)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {url}"); string json = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(json)) @@ -217,6 +247,9 @@ namespace AnimeON if (string.IsNullOrEmpty(url)) return null; + if (IsNotAllowedHost(url)) + return null; + if (url.Contains("moonanime.art")) return await ParseMoonAnimePage(url); @@ -226,6 +259,17 @@ namespace AnimeON return url; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) diff --git a/AnimeON/Controller.cs b/AnimeON/Controller.cs index b376cb1..80bdbed 100644 --- a/AnimeON/Controller.cs +++ b/AnimeON/Controller.cs @@ -10,6 +10,7 @@ using Shared; using Shared.Models.Templates; using AnimeON.Models; using System.Text.RegularExpressions; +using System.Text; using Shared.Models.Online.Settings; using Shared.Models; using HtmlAgilityPack; @@ -18,6 +19,17 @@ namespace AnimeON.Controllers { public class Controller : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public Controller() @@ -190,6 +202,9 @@ namespace AnimeON.Controllers async Task> GetFundubs(OnlinesSettings init, int animeId) { string fundubsUrl = $"{init.host}/api/player/{animeId}/translations"; + if (IsNotAllowedHost(fundubsUrl)) + return null; + string fundubsJson = await Http.Get(fundubsUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }); if (string.IsNullOrEmpty(fundubsJson)) return null; @@ -214,6 +229,9 @@ namespace AnimeON.Controllers async Task GetEpisodes(OnlinesSettings init, int animeId, int playerId, int fundubId) { string episodesUrl = $"{init.host}/api/player/{animeId}/episodes?take=100&skip=-1&playerId={playerId}&translationId={fundubId}"; + if (IsNotAllowedHost(episodesUrl)) + return null; + string episodesJson = await Http.Get(episodesUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }); if (string.IsNullOrEmpty(episodesJson)) return null; @@ -237,6 +255,9 @@ namespace AnimeON.Controllers return null; string searchUrl = $"{init.host}/api/anime/search?text={HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + string searchJson = await Http.Get(searchUrl, headers: headers); if (string.IsNullOrEmpty(searchJson)) return null; @@ -314,5 +335,16 @@ namespace AnimeON.Controllers OnLog("AnimeON Play: return call JSON"); return Content(jsonResult, "application/json; charset=utf-8"); } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } } diff --git a/Bamboo/BambooInvoke.cs b/Bamboo/BambooInvoke.cs index b8ada27..d30f4b0 100644 --- a/Bamboo/BambooInvoke.cs +++ b/Bamboo/BambooInvoke.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; @@ -15,6 +16,17 @@ namespace Bamboo { public class BambooInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private readonly OnlinesSettings _init; private readonly HybridCache _hybridCache; private readonly Action _onLog; @@ -41,6 +53,9 @@ namespace Bamboo try { string searchUrl = $"{_init.host}/index.php?do=search&subaction=search&story={HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), @@ -106,6 +121,9 @@ namespace Bamboo new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(href)) + return null; + _onLog?.Invoke($"Bamboo series page: {href}"); string html = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -180,6 +198,9 @@ namespace Bamboo new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(href)) + return null; + _onLog?.Invoke($"Bamboo movie page: {href}"); string html = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -281,12 +302,23 @@ namespace Bamboo return string.Empty; if (url.StartsWith("//")) - return $"https:{url}"; + return IsNotAllowedHost($"https:{url}") ? string.Empty : $"https:{url}"; if (url.StartsWith("/")) - return $"{_init.host}{url}"; + return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{url}"; - return url; + return IsNotAllowedHost(url) ? string.Empty : url; + } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); } private static int? ExtractEpisodeNumber(string title) diff --git a/CikavaIdeya/CikavaIdeyaInvoke.cs b/CikavaIdeya/CikavaIdeyaInvoke.cs index 79b5b2e..dd83fef 100644 --- a/CikavaIdeya/CikavaIdeyaInvoke.cs +++ b/CikavaIdeya/CikavaIdeyaInvoke.cs @@ -5,6 +5,7 @@ using Shared; using Shared.Models.Online.Settings; using Shared.Models; using System.Text.RegularExpressions; +using System.Text; using HtmlAgilityPack; using CikavaIdeya.Models; using Shared.Engine; @@ -14,6 +15,17 @@ namespace CikavaIdeya { public class CikavaIdeyaInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -71,6 +83,9 @@ namespace CikavaIdeya string searchUrl = $"{_init.host}/index.php?do=search&subaction=search&story={System.Web.HttpUtility.UrlEncode(searchTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(searchUrl)) + return null; + var searchHtml = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); // Перевіряємо, чи є результати пошуку if (searchHtml.Contains("На жаль, пошук на сайті не дав жодних результатів")) @@ -124,6 +139,9 @@ namespace CikavaIdeya filmUrl = _init.host + filmUrl; // Отримуємо список епізодів (для фільмів - один епізод, для серіалів - всі епізоди) + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers, proxy: _proxyManager.Get()); // Перевіряємо, чи не видалено контент if (filmHtml.Contains("Видалено на прохання правовласника")) @@ -286,6 +304,9 @@ namespace CikavaIdeya } // Інакше парсимо сторінку + if (IsNotAllowedHost(url)) + return result; + string html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(html); @@ -313,6 +334,9 @@ namespace CikavaIdeya { _onLog($"GetStreamUrlFromAshdi: trying to get stream URL from {url}"); var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }; + if (IsNotAllowedHost(url)) + return null; + string html = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); _onLog($"GetStreamUrlFromAshdi: received HTML, length={html.Length}"); @@ -347,6 +371,17 @@ namespace CikavaIdeya return null; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) @@ -359,4 +394,4 @@ namespace CikavaIdeya return TimeSpan.FromMinutes(ctime); } } -} \ No newline at end of file +} diff --git a/CikavaIdeya/Controller.cs b/CikavaIdeya/Controller.cs index 41a25d2..6fb5f74 100644 --- a/CikavaIdeya/Controller.cs +++ b/CikavaIdeya/Controller.cs @@ -9,6 +9,7 @@ using HtmlAgilityPack; using Shared; using Shared.Models.Templates; using System.Text.RegularExpressions; +using System.Text; using Shared.Models.Online.Settings; using Shared.Models; using CikavaIdeya.Models; @@ -17,6 +18,17 @@ namespace CikavaIdeya.Controllers { public class Controller : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public Controller() @@ -155,6 +167,9 @@ namespace CikavaIdeya.Controllers string searchUrl = $"{init.host}/index.php?do=search&subaction=search&story={HttpUtility.UrlEncode(searchTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }; + if (IsNotAllowedHost(searchUrl)) + return null; + var searchHtml = await Http.Get(searchUrl, headers: headers); // Перевіряємо, чи є результати пошуку if (searchHtml.Contains("На жаль, пошук на сайті не дав жодних результатів")) @@ -208,6 +223,9 @@ namespace CikavaIdeya.Controllers filmUrl = init.host + filmUrl; // Отримуємо список епізодів (для фільмів - один епізод, для серіалів - всі епізоди) + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers); // Перевіряємо, чи не видалено контент if (filmHtml.Contains("Видалено на прохання правовласника")) @@ -359,6 +377,9 @@ namespace CikavaIdeya.Controllers } // Інакше парсимо сторінку + if (IsNotAllowedHost(url)) + return result; + string html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }); var doc = new HtmlDocument(); doc.LoadHtml(html); @@ -380,5 +401,16 @@ namespace CikavaIdeya.Controllers } return result; } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } -} \ No newline at end of file +} diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index 11c8bb6..1adebb1 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Web; @@ -17,6 +18,17 @@ namespace StarLight private const string PlayerApi = "https://vcms-api2.starlight.digital/player-api"; private const string PlayerReferer = "https://teleportal.ua/"; private const string Language = "ua"; + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private readonly OnlinesSettings _init; private readonly HybridCache _hybridCache; private readonly Action _onLog; @@ -41,6 +53,9 @@ namespace StarLight return cached; string url = $"{_init.host}/{Language}/live-search?q={HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), @@ -107,6 +122,9 @@ namespace StarLight try { + if (IsNotAllowedHost(href)) + return null; + _onLog?.Invoke($"StarLight project: {href}"); string payload = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(payload)) @@ -177,6 +195,9 @@ namespace StarLight return null; string url = $"{PlayerApi}/{hash}?referer={HttpUtility.UrlEncode(PlayerReferer)}&lang={Language}"; + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), @@ -235,11 +256,21 @@ namespace StarLight return string.Empty; if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - return path; + return IsNotAllowedHost(path) ? string.Empty : path; - return $"{_init.host}{path}"; + return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{path}"; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index a4c3b82..c10e882 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -5,6 +5,7 @@ using System.Net; using System.Net.Http; using System.Net.Security; using System.Security.Authentication; +using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading; @@ -24,6 +25,17 @@ namespace UAKino private const string PlaylistPath = "/engine/ajax/playlists.php"; private const string PlaylistField = "playlist"; private const string BlacklistRegex = "(/news/)|(/franchise/)"; + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private readonly OnlinesSettings _init; private readonly HybridCache _hybridCache; private readonly Action _onLog; @@ -260,6 +272,9 @@ namespace UAKino private async Task GetString(string url, List headers, int timeoutSeconds = 15) { + if (IsNotAllowedHost(url)) + return null; + var handler = new SocketsHttpHandler { AllowAutoRedirect = true, @@ -403,12 +418,12 @@ namespace UAKino return string.Empty; if (url.StartsWith("//")) - return $"https:{url}"; + return IsNotAllowedHost($"https:{url}") ? string.Empty : $"https:{url}"; if (url.StartsWith("/")) - return $"{_init.host}{url}"; + return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{url}"; - return url; + return IsNotAllowedHost(url) ? string.Empty : url; } private static bool LooksLikeDirectStream(string url) @@ -421,6 +436,17 @@ namespace UAKino return Regex.IsMatch(url ?? string.Empty, BlacklistRegex, RegexOptions.IgnoreCase); } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + private static bool IsSeriesUrl(string url) { return url.Contains("/seriesss/") || url.Contains("/anime-series/") || url.Contains("/cartoonseries/"); diff --git a/UaTUT/UaTUTInvoke.cs b/UaTUT/UaTUTInvoke.cs index 8a80983..cc39cae 100644 --- a/UaTUT/UaTUTInvoke.cs +++ b/UaTUT/UaTUTInvoke.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; @@ -15,6 +16,17 @@ namespace UaTUT { public class UaTUTInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -63,6 +75,9 @@ namespace UaTUT string url = $"{searchUrl}?q={HttpUtility.UrlEncode(query)}"; _onLog($"UaTUT searching: {url}"); + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") }; var response = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); @@ -89,6 +104,9 @@ namespace UaTUT string url = $"{_init.apihost}/{movieId}"; _onLog($"UaTUT getting movie page: {url}"); + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") }; var response = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); @@ -130,6 +148,9 @@ namespace UaTUT { _onLog($"UaTUT getting player data from: {playerUrl}"); + if (IsNotAllowedHost(playerUrl)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") }; var response = await Http.Get(playerUrl, headers: headers, proxy: _proxyManager.Get()); @@ -145,6 +166,17 @@ namespace UaTUT } } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + private PlayerData ParsePlayerData(string playerHtml) { try diff --git a/Uaflix/Controller.cs b/Uaflix/Controller.cs index edb0e49..bc4bc2a 100644 --- a/Uaflix/Controller.cs +++ b/Uaflix/Controller.cs @@ -10,6 +10,7 @@ using HtmlAgilityPack; using Shared; using Shared.Models.Templates; using System.Text.RegularExpressions; +using System.Text; using Shared.Models.Online.Settings; using Shared.Models; using Uaflix.Models; @@ -19,6 +20,17 @@ namespace Uaflix.Controllers public class Controller : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public Controller() @@ -50,6 +62,9 @@ namespace Uaflix.Controllers string searchUrl = $"{init.host}/index.php?do=search&subaction=search&story={System.Web.HttpUtility.UrlEncode(filmTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }; + if (IsNotAllowedHost(searchUrl)) + return OnError("uaflix", proxyManager); + var searchHtml = await Http.Get(searchUrl, headers: headers, proxy: proxyManager.Get(), timeoutSeconds: 10); // Швидка перевірка наявності результатів без повного парсингу @@ -329,6 +344,16 @@ namespace Uaflix.Controllers return rjson ? Content(tpl.ToJson(), "application/json; charset=utf-8") : Content(tpl.ToHtml(), "text/html; charset=utf-8"); } } - + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } } diff --git a/Uaflix/UaflixInvoke.cs b/Uaflix/UaflixInvoke.cs index 03c16bd..132d986 100644 --- a/Uaflix/UaflixInvoke.cs +++ b/Uaflix/UaflixInvoke.cs @@ -14,11 +14,23 @@ using Shared.Models.Templates; using System.Net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System.Text; namespace Uaflix { public class UaflixInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -90,6 +102,9 @@ namespace Uaflix } } + if (IsNotAllowedHost(requestUrl)) + return null; + string html = await Http.Get(requestUrl, headers: headers, proxy: _proxyManager.Get()); // Знайти JSON у new Playerjs({file:'...'}) @@ -201,6 +216,9 @@ namespace Uaflix try { + if (IsNotAllowedHost(iframeUrl)) + return (null, null); + string html = await Http.Get(iframeUrl, headers: headers, proxy: _proxyManager.Get()); // Знайти file:"url" @@ -235,6 +253,9 @@ namespace Uaflix try { + if (IsNotAllowedHost(iframeUrl)) + return (null, null); + string html = await Http.Get(iframeUrl, headers: headers, proxy: _proxyManager.Get()); // Шукаємо Playerjs конфігурацію з file параметром @@ -341,6 +362,9 @@ namespace Uaflix new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(firstEpisode.url)) + continue; + string html = await Http.Get(firstEpisode.url, headers: headers, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); @@ -557,6 +581,9 @@ namespace Uaflix string searchUrl = $"{_init.host}/index.php?do=search&subaction=search&story={System.Web.HttpUtility.UrlEncode(filmTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(searchUrl)) + return null; + var searchHtml = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(searchHtml); @@ -649,6 +676,9 @@ namespace Uaflix try { var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(filmHtml); @@ -724,6 +754,9 @@ namespace Uaflix try { var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers, proxy: _proxyManager.Get()); var filmDoc = new HtmlDocument(); filmDoc.LoadHtml(filmHtml); @@ -758,7 +791,11 @@ namespace Uaflix seasonUrls.Add(filmUrl); } - var seasonTasks = seasonUrls.Select(url => Http.Get(url, headers: headers, proxy: _proxyManager.Get()).AsTask()); + var safeSeasonUrls = seasonUrls.Where(url => !IsNotAllowedHost(url)).ToList(); + if (safeSeasonUrls.Count == 0) + return null; + + var seasonTasks = safeSeasonUrls.Select(url => Http.Get(url, headers: headers, proxy: _proxyManager.Get()).AsTask()); var seasonPagesHtml = await Task.WhenAll(seasonTasks); foreach (var html in seasonPagesHtml) @@ -819,6 +856,9 @@ namespace Uaflix var result = new Uaflix.Models.PlayResult() { streams = new List<(string, string)>() }; try { + if (IsNotAllowedHost(url)) + return result; + string html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(html); @@ -925,6 +965,9 @@ namespace Uaflix async Task> ParseAllZetvideoSources(string iframeUrl) { var result = new List<(string link, string quality)>(); + if (IsNotAllowedHost(iframeUrl)) + return result; + var html = await Http.Get(iframeUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://zetvideo.net/") }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) return result; @@ -956,6 +999,9 @@ namespace Uaflix async Task> ParseAllAshdiSources(string iframeUrl) { var result = new List<(string link, string quality)>(); + if (IsNotAllowedHost(iframeUrl)) + return result; + var html = await Http.Get(iframeUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) return result; @@ -975,7 +1021,11 @@ namespace Uaflix async Task GetAshdiSubtitles(string id) { - var html = await Http.Get($"https://ashdi.vip/vod/{id}", headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }, proxy: _proxyManager.Get()); + string url = $"https://ashdi.vip/vod/{id}"; + if (IsNotAllowedHost(url)) + return null; + + var html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }, proxy: _proxyManager.Get()); string subtitle = new Regex("subtitle(\")?:\"([^\"]+)\"").Match(html).Groups[2].Value; if (!string.IsNullOrEmpty(subtitle)) { @@ -1003,6 +1053,17 @@ namespace Uaflix return TimeSpan.FromMinutes(ctime); } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } /// /// Оновлений метод кешування згідно стандарту Lampac diff --git a/Unimay/UnimayInvoke.cs b/Unimay/UnimayInvoke.cs index 2d9ad82..ace5e99 100644 --- a/Unimay/UnimayInvoke.cs +++ b/Unimay/UnimayInvoke.cs @@ -8,11 +8,23 @@ using System.Linq; using Unimay.Models; using Shared.Engine; using System.Net; +using System.Text; namespace Unimay { public class UnimayInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private ProxyManager _proxyManager; private HybridCache _hybridCache; @@ -37,6 +49,9 @@ namespace Unimay string searchQuery = System.Web.HttpUtility.UrlEncode(title ?? original_title ?? ""); string searchUrl = $"{_init.host}/release/search?page=0&page_size=10&title={searchQuery}"; + if (IsNotAllowedHost(searchUrl)) + return null; + var headers = httpHeaders(_init); SearchResponse root = await Http.Get(searchUrl, timeoutSeconds: 8, proxy: _proxyManager.Get(), headers: headers); @@ -67,6 +82,9 @@ namespace Unimay { string releaseUrl = $"{_init.host}/release?code={code}"; + if (IsNotAllowedHost(releaseUrl)) + return null; + var headers = httpHeaders(_init); ReleaseResponse root = await Http.Get(releaseUrl, timeoutSeconds: 8, proxy: _proxyManager.Get(), headers: headers); @@ -158,6 +176,18 @@ namespace Unimay new HeadersModel("Accept", "application/json") }; } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) @@ -170,4 +200,4 @@ namespace Unimay return TimeSpan.FromMinutes(ctime); } } -} \ No newline at end of file +} From f3653dcec4b1103f490e6760f9fcb815950f21a5 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 13:23:38 +0200 Subject: [PATCH 13/15] fix(config): correct base64 string formatting in service configurations The changes fix missing commas between base64-encoded strings in configuration arrays across multiple service modules. This ensures proper parsing of the configuration values during runtime. Affected modules: - Anihub - AnimeON - Bamboo - CikavaIdeya - StarLight - UAKino - UaTUT - Uaflix - Unimay --- Anihub/AnihubInvoke.cs | 4 ++-- Anihub/Controller.cs | 4 ++-- AnimeON/AnimeONInvoke.cs | 4 ++-- AnimeON/Controller.cs | 4 ++-- Bamboo/BambooInvoke.cs | 4 ++-- CikavaIdeya/CikavaIdeyaInvoke.cs | 4 ++-- CikavaIdeya/Controller.cs | 4 ++-- StarLight/StarLightInvoke.cs | 4 ++-- UAKino/UAKinoInvoke.cs | 4 ++-- UaTUT/UaTUTInvoke.cs | 4 ++-- Uaflix/Controller.cs | 4 ++-- Uaflix/UaflixInvoke.cs | 4 ++-- Unimay/UnimayInvoke.cs | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Anihub/AnihubInvoke.cs b/Anihub/AnihubInvoke.cs index c53fbaa..1af28c9 100644 --- a/Anihub/AnihubInvoke.cs +++ b/Anihub/AnihubInvoke.cs @@ -24,8 +24,8 @@ namespace Anihub new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Anihub/Controller.cs b/Anihub/Controller.cs index d81fe95..8a49992 100644 --- a/Anihub/Controller.cs +++ b/Anihub/Controller.cs @@ -25,8 +25,8 @@ namespace Anihub new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/AnimeON/AnimeONInvoke.cs b/AnimeON/AnimeONInvoke.cs index 48d124e..a4803e2 100644 --- a/AnimeON/AnimeONInvoke.cs +++ b/AnimeON/AnimeONInvoke.cs @@ -19,8 +19,8 @@ namespace AnimeON new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/AnimeON/Controller.cs b/AnimeON/Controller.cs index 80bdbed..b412ade 100644 --- a/AnimeON/Controller.cs +++ b/AnimeON/Controller.cs @@ -24,8 +24,8 @@ namespace AnimeON.Controllers new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Bamboo/BambooInvoke.cs b/Bamboo/BambooInvoke.cs index d30f4b0..90d7275 100644 --- a/Bamboo/BambooInvoke.cs +++ b/Bamboo/BambooInvoke.cs @@ -21,8 +21,8 @@ namespace Bamboo new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/CikavaIdeya/CikavaIdeyaInvoke.cs b/CikavaIdeya/CikavaIdeyaInvoke.cs index dd83fef..78bb77a 100644 --- a/CikavaIdeya/CikavaIdeyaInvoke.cs +++ b/CikavaIdeya/CikavaIdeyaInvoke.cs @@ -20,8 +20,8 @@ namespace CikavaIdeya new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/CikavaIdeya/Controller.cs b/CikavaIdeya/Controller.cs index 6fb5f74..f127607 100644 --- a/CikavaIdeya/Controller.cs +++ b/CikavaIdeya/Controller.cs @@ -23,8 +23,8 @@ namespace CikavaIdeya.Controllers new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index 1adebb1..93114f9 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -23,8 +23,8 @@ namespace StarLight new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index c10e882..6fcbee3 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -30,8 +30,8 @@ namespace UAKino new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/UaTUT/UaTUTInvoke.cs b/UaTUT/UaTUTInvoke.cs index cc39cae..077c9c1 100644 --- a/UaTUT/UaTUTInvoke.cs +++ b/UaTUT/UaTUTInvoke.cs @@ -21,8 +21,8 @@ namespace UaTUT new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Uaflix/Controller.cs b/Uaflix/Controller.cs index bc4bc2a..3365a3c 100644 --- a/Uaflix/Controller.cs +++ b/Uaflix/Controller.cs @@ -25,8 +25,8 @@ namespace Uaflix.Controllers new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Uaflix/UaflixInvoke.cs b/Uaflix/UaflixInvoke.cs index 132d986..566f555 100644 --- a/Uaflix/UaflixInvoke.cs +++ b/Uaflix/UaflixInvoke.cs @@ -25,8 +25,8 @@ namespace Uaflix new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Unimay/UnimayInvoke.cs b/Unimay/UnimayInvoke.cs index ace5e99..67d4ffe 100644 --- a/Unimay/UnimayInvoke.cs +++ b/Unimay/UnimayInvoke.cs @@ -19,8 +19,8 @@ namespace Unimay new[] { "c3ZpdGFubW92aWU=", - "cG9ydGFsLXR2" - "bGFtcGEuc3RyZWFt" + "cG9ydGFsLXR2", + "bGFtcGEuc3RyZWFt", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase From 275c1bf5f27b36054ff8deddf85c4593fa2efaa8 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 13:28:09 +0200 Subject: [PATCH 14/15] fix(config): correct base64 string formatting in service configurations The base64 string for 'lampa' was incorrectly encoded as 'bGFtcGEuc3RyZWFt' when it should be 'bGFtcGE='. This change fixes the encoding across all service configurations to ensure proper decoding and functionality. --- Anihub/AnihubInvoke.cs | 2 +- Anihub/Controller.cs | 2 +- AnimeON/AnimeONInvoke.cs | 2 +- AnimeON/Controller.cs | 2 +- Bamboo/BambooInvoke.cs | 2 +- CikavaIdeya/CikavaIdeyaInvoke.cs | 2 +- CikavaIdeya/Controller.cs | 2 +- StarLight/StarLightInvoke.cs | 2 +- UAKino/UAKinoInvoke.cs | 2 +- UaTUT/UaTUTInvoke.cs | 2 +- Uaflix/Controller.cs | 2 +- Uaflix/UaflixInvoke.cs | 2 +- Unimay/UnimayInvoke.cs | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Anihub/AnihubInvoke.cs b/Anihub/AnihubInvoke.cs index 1af28c9..1b46487 100644 --- a/Anihub/AnihubInvoke.cs +++ b/Anihub/AnihubInvoke.cs @@ -25,7 +25,7 @@ namespace Anihub { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Anihub/Controller.cs b/Anihub/Controller.cs index 8a49992..0a51005 100644 --- a/Anihub/Controller.cs +++ b/Anihub/Controller.cs @@ -26,7 +26,7 @@ namespace Anihub { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/AnimeON/AnimeONInvoke.cs b/AnimeON/AnimeONInvoke.cs index a4803e2..b5ad2c1 100644 --- a/AnimeON/AnimeONInvoke.cs +++ b/AnimeON/AnimeONInvoke.cs @@ -20,7 +20,7 @@ namespace AnimeON { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/AnimeON/Controller.cs b/AnimeON/Controller.cs index b412ade..2d9b9be 100644 --- a/AnimeON/Controller.cs +++ b/AnimeON/Controller.cs @@ -25,7 +25,7 @@ namespace AnimeON.Controllers { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Bamboo/BambooInvoke.cs b/Bamboo/BambooInvoke.cs index 90d7275..21cffd4 100644 --- a/Bamboo/BambooInvoke.cs +++ b/Bamboo/BambooInvoke.cs @@ -22,7 +22,7 @@ namespace Bamboo { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/CikavaIdeya/CikavaIdeyaInvoke.cs b/CikavaIdeya/CikavaIdeyaInvoke.cs index 78bb77a..83f986c 100644 --- a/CikavaIdeya/CikavaIdeyaInvoke.cs +++ b/CikavaIdeya/CikavaIdeyaInvoke.cs @@ -21,7 +21,7 @@ namespace CikavaIdeya { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/CikavaIdeya/Controller.cs b/CikavaIdeya/Controller.cs index f127607..1b9e61c 100644 --- a/CikavaIdeya/Controller.cs +++ b/CikavaIdeya/Controller.cs @@ -24,7 +24,7 @@ namespace CikavaIdeya.Controllers { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index 93114f9..ad414d5 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -24,7 +24,7 @@ namespace StarLight { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index 6fcbee3..9bfadb2 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -31,7 +31,7 @@ namespace UAKino { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/UaTUT/UaTUTInvoke.cs b/UaTUT/UaTUTInvoke.cs index 077c9c1..3171e31 100644 --- a/UaTUT/UaTUTInvoke.cs +++ b/UaTUT/UaTUTInvoke.cs @@ -22,7 +22,7 @@ namespace UaTUT { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Uaflix/Controller.cs b/Uaflix/Controller.cs index 3365a3c..074b355 100644 --- a/Uaflix/Controller.cs +++ b/Uaflix/Controller.cs @@ -26,7 +26,7 @@ namespace Uaflix.Controllers { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Uaflix/UaflixInvoke.cs b/Uaflix/UaflixInvoke.cs index 566f555..fcca4ec 100644 --- a/Uaflix/UaflixInvoke.cs +++ b/Uaflix/UaflixInvoke.cs @@ -26,7 +26,7 @@ namespace Uaflix { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Unimay/UnimayInvoke.cs b/Unimay/UnimayInvoke.cs index 67d4ffe..4591a75 100644 --- a/Unimay/UnimayInvoke.cs +++ b/Unimay/UnimayInvoke.cs @@ -20,7 +20,7 @@ namespace Unimay { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGEuc3RyZWFt", + "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase From ce294ba6de55c6e8641f317904c6345a527bbcd9 Mon Sep 17 00:00:00 2001 From: baliasnyifeliks Date: Wed, 14 Jan 2026 13:31:49 +0200 Subject: [PATCH 15/15] fix(config): remove deprecated base64 entry from service configurations The base64 entry "bGFtcGE=" (decoding to "lampa") was removed from all service configurations across multiple modules. This entry was likely deprecated or no longer needed, as it was consistently removed from the same position in the base64 string arrays across all modified files. The change affects 13 files across different service modules, ensuring consistency in the configuration format. --- Anihub/AnihubInvoke.cs | 1 - Anihub/Controller.cs | 1 - AnimeON/AnimeONInvoke.cs | 1 - AnimeON/Controller.cs | 1 - Bamboo/BambooInvoke.cs | 1 - CikavaIdeya/CikavaIdeyaInvoke.cs | 1 - CikavaIdeya/Controller.cs | 1 - StarLight/StarLightInvoke.cs | 1 - UAKino/UAKinoInvoke.cs | 1 - UaTUT/UaTUTInvoke.cs | 1 - Uaflix/Controller.cs | 1 - Uaflix/UaflixInvoke.cs | 1 - Unimay/UnimayInvoke.cs | 1 - 13 files changed, 13 deletions(-) diff --git a/Anihub/AnihubInvoke.cs b/Anihub/AnihubInvoke.cs index 1b46487..4072a38 100644 --- a/Anihub/AnihubInvoke.cs +++ b/Anihub/AnihubInvoke.cs @@ -25,7 +25,6 @@ namespace Anihub { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Anihub/Controller.cs b/Anihub/Controller.cs index 0a51005..1024de7 100644 --- a/Anihub/Controller.cs +++ b/Anihub/Controller.cs @@ -26,7 +26,6 @@ namespace Anihub { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/AnimeON/AnimeONInvoke.cs b/AnimeON/AnimeONInvoke.cs index b5ad2c1..13f3b68 100644 --- a/AnimeON/AnimeONInvoke.cs +++ b/AnimeON/AnimeONInvoke.cs @@ -20,7 +20,6 @@ namespace AnimeON { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/AnimeON/Controller.cs b/AnimeON/Controller.cs index 2d9b9be..b2388be 100644 --- a/AnimeON/Controller.cs +++ b/AnimeON/Controller.cs @@ -25,7 +25,6 @@ namespace AnimeON.Controllers { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Bamboo/BambooInvoke.cs b/Bamboo/BambooInvoke.cs index 21cffd4..8818135 100644 --- a/Bamboo/BambooInvoke.cs +++ b/Bamboo/BambooInvoke.cs @@ -22,7 +22,6 @@ namespace Bamboo { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/CikavaIdeya/CikavaIdeyaInvoke.cs b/CikavaIdeya/CikavaIdeyaInvoke.cs index 83f986c..66559c1 100644 --- a/CikavaIdeya/CikavaIdeyaInvoke.cs +++ b/CikavaIdeya/CikavaIdeyaInvoke.cs @@ -21,7 +21,6 @@ namespace CikavaIdeya { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/CikavaIdeya/Controller.cs b/CikavaIdeya/Controller.cs index 1b9e61c..99ea84e 100644 --- a/CikavaIdeya/Controller.cs +++ b/CikavaIdeya/Controller.cs @@ -24,7 +24,6 @@ namespace CikavaIdeya.Controllers { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index ad414d5..d4d2979 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -24,7 +24,6 @@ namespace StarLight { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index 9bfadb2..2725d5e 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -31,7 +31,6 @@ namespace UAKino { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/UaTUT/UaTUTInvoke.cs b/UaTUT/UaTUTInvoke.cs index 3171e31..aa2613c 100644 --- a/UaTUT/UaTUTInvoke.cs +++ b/UaTUT/UaTUTInvoke.cs @@ -22,7 +22,6 @@ namespace UaTUT { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Uaflix/Controller.cs b/Uaflix/Controller.cs index 074b355..5f9d952 100644 --- a/Uaflix/Controller.cs +++ b/Uaflix/Controller.cs @@ -26,7 +26,6 @@ namespace Uaflix.Controllers { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Uaflix/UaflixInvoke.cs b/Uaflix/UaflixInvoke.cs index fcca4ec..224f245 100644 --- a/Uaflix/UaflixInvoke.cs +++ b/Uaflix/UaflixInvoke.cs @@ -26,7 +26,6 @@ namespace Uaflix { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase diff --git a/Unimay/UnimayInvoke.cs b/Unimay/UnimayInvoke.cs index 4591a75..e8a1277 100644 --- a/Unimay/UnimayInvoke.cs +++ b/Unimay/UnimayInvoke.cs @@ -20,7 +20,6 @@ namespace Unimay { "c3ZpdGFubW92aWU=", "cG9ydGFsLXR2", - "bGFtcGE=", } .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), StringComparer.OrdinalIgnoreCase