using Shared.Engine.RxEnumerate; using Shared.Models.Base; using Shared.Models.Online.Eneyida; using Shared.Models.Templates; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using System.Web; namespace Shared.Engine.Online { public struct KinoukrInvoke { #region unic static string ArrayList => "qwertyuioplkjhgfdsazxcvbnm"; static string ArrayListToNumber => "1234567890"; public static string unic(int size = 8, bool IsNumberCode = false) { StringBuilder array = new StringBuilder(size); for (int i = 0; i < size; i++) { array.Append(IsNumberCode ? ArrayListToNumber[Random.Shared.Next(0, ArrayListToNumber.Length)] : ArrayList[Random.Shared.Next(0, ArrayList.Length)]); } return array.ToString(); } #endregion #region KinoukrInvoke string host; string apihost; HttpHydra http; Func onstreamfile; Func onlog; Action requesterror; public KinoukrInvoke(string host, string apihost, HttpHydra httpHydra, Func onstreamfile, Func onlog = null, Action requesterror = null) { this.host = host != null ? $"{host}/" : null; this.apihost = apihost; http = httpHydra; this.onstreamfile = onstreamfile; this.onlog = onlog; this.requesterror = requesterror; } #endregion #region Embed public async Task Embed(string original_title, int year, string href) { if (string.IsNullOrWhiteSpace(href) && (string.IsNullOrWhiteSpace(original_title) || year == 0)) return null; return null; //string link = href; //var result = new EmbedModel(); //if (string.IsNullOrWhiteSpace(link)) //{ // onlog?.Invoke("search start"); // //string? search = await onget.Invoke($"{apihost}/index.php?do=search&subaction=search&from_page=0&story={HttpUtility.UrlEncode(original_title)}"); // // $"{apihost}/index.php?do=search" // string search = await onpost.Invoke($"{apihost}/{unic(4, true)}-{unic(Random.Shared.Next(4, 8))}-{unic(Random.Shared.Next(5, 10))}.html", $"do=search&subaction=search&story={HttpUtility.UrlEncode(original_title)}"); // if (search == null) // { // requesterror?.Invoke(); // return null; // } // onlog?.Invoke("search ok"); // foreach (string row in search.Split("\"short clearfix with-mask\"").Skip(1)) // { // if (row.Contains(">Анонс") || row.Contains(">Трейлер")) // continue; // string newslink = Regex.Match(row, "href=\"(https?://[^/]+/[^\"]+\\.html)\"").Groups[1].Value; // if (string.IsNullOrWhiteSpace(newslink)) // continue; // string name = Regex.Match(row, "class=\"short-title\" [^>]+>([^<]+)<").Groups[1].Value; // if (result.similars == null) // result.similars = new List(); // result.similars.Add(new Similar() // { // title = name, // href = newslink // }); // } // if (result.similars == null || result.similars.Count == 0) // { // if (search.Contains(">Пошук по сайту<")) // return new EmbedModel() { IsEmpty = true }; // return null; // } // if (result.similars.Count > 1) // return result; // link = result.similars[0].href; //} //onlog?.Invoke("link: " + link); //string news = await onget.Invoke(link); //if (news == null) //{ // requesterror?.Invoke(); // return null; //} //result.quel = Regex.Match(news, "class=\"m-meta m-qual\">([^<]+)<").Groups[1].Value; //string iframeUri = Regex.Match(news, "src=\"(https?://tortuga\\.[a-z]+/[^\"]+)\"").Groups[1].Value; //if (string.IsNullOrEmpty(iframeUri)) //{ // iframeUri = Regex.Match(news, "src=\"(https?://ashdi\\.vip/[^\"]+)\"").Groups[1].Value; // if (string.IsNullOrEmpty(iframeUri)) // return null; //} //onlog?.Invoke("iframeUri: " + iframeUri); //string content = await onget.Invoke(iframeUri); //if (content == null || !content.Contains("file:")) //{ // requesterror?.Invoke(); // return null; //} //string player = StringConvert.FindLastText(content, "new Playerjs", ""); //if (player == null) // return null; //if (Regex.IsMatch(content, "file: ?'\\[")) //{ // Models.Online.Tortuga.Voice[] root = null; // try // { // root = JsonSerializer.Deserialize(Regex.Match(content, "file: ?'([^\n\r]+)',").Groups[1].Value); // if (root == null || root.Length == 0) // return null; // } // catch { return null; } // result.serial = root; //} //else //{ // result.content = player; // onlog?.Invoke("content: " + result.content); //} //return result; } #endregion #region EmbedKurwa public async Task EmbedKurwa(int clarification, string title, string original_title, int year, string href) { string iframeUri = href; var result = new EmbedModel(); if (string.IsNullOrEmpty(iframeUri)) { string arg = clarification == 1 || string.IsNullOrWhiteSpace(original_title) ? $"name={HttpUtility.UrlEncode(title)}" : $"eng_name={HttpUtility.UrlEncode(original_title)}"; var root = await http.Get("http://194.246.82.144/ukr?" + arg); if (root == null) { requesterror?.Invoke(); return null; } result.similars = new List(root.Length); foreach (var item in root) { var model = new Similar() { href = item.tortuga ?? item.ashdi, title = $"{item.name} / {item.eng_name}", year = item.year }; if (item.year == year.ToString()) result.similars.Insert(0, model); else result.similars.Add(model); } if (result.similars.Count == 0) return new EmbedModel() { IsEmpty = true }; if (result.similars.Count > 1 && result.similars[0].year != year.ToString()) return result; iframeUri = result.similars[0].href; } onlog?.Invoke("iframeUri: " + iframeUri); await http.GetSpan(iframeUri, content => { if (!content.Contains("file:", StringComparison.Ordinal)) return; if (iframeUri.Contains("ashdi")) { result.source_type = "ashdi"; if (Regex.IsMatch(content, "file: ?'\\[")) { try { var root = JsonSerializer.Deserialize(Rx.Match(content, "file: ?'([^\n\r]+)',")); if (root != null && root.Length > 0) result.serial_ashdi = root; } catch { } } else { var rx = Rx.Split("new Playerjs", content); if (1 > rx.Count) return; result.content = rx[1].ToString(); } } else { result.source_type = "tortuga"; if (Regex.IsMatch(content, "file: ?'")) { try { string file = Rx.Match(content, "file: ?'([^\n\r]+)',"); if (file.EndsWith("==")) { file = Regex.Replace(file, "==$", ""); file = string.Join("", CrypTo.DecodeBase64(file).Reverse()); } var root = JsonSerializer.Deserialize(file); if (root != null && root.Length > 0) result.serial = root; } catch { } } else { result.content = content.ToString(); } } }); if (string.IsNullOrEmpty(result.content) && result.serial_ashdi == null && result.serial == null) { requesterror?.Invoke(); return null; } return result; } #endregion #region getIframeSource public async Task getIframeSource(string link) { if (string.IsNullOrWhiteSpace(link)) return null; string iframeUri = null; await http.GetSpan(link, news => { iframeUri = Rx.Match(news, "src=\"(https?://tortuga\\.[a-z]+/[^\"]+)\""); if (string.IsNullOrEmpty(iframeUri)) iframeUri = Rx.Match(news, "src=\"(https?://ashdi\\.vip/[^\"]+)\""); }); if (string.IsNullOrEmpty(iframeUri)) { requesterror?.Invoke(); return null; } return iframeUri; } #endregion #region Tpl public ITplResult Tpl(EmbedModel result, int clarification, string title, string original_title, int year, string t, int s, string href, VastConf vast = null, bool rjson = false) { if (result == null || result.IsEmpty) return default; string enc_title = HttpUtility.UrlEncode(title); string enc_original_title = HttpUtility.UrlEncode(original_title); string enc_href = HttpUtility.UrlEncode(href); #region similar if (result.content == null && result.serial == null && result.serial_ashdi == null) { if (string.IsNullOrWhiteSpace(href) && result.similars != null && result.similars.Count > 0) { var stpl = new SimilarTpl(result.similars.Count); foreach (var similar in result.similars) { string link = host + $"lite/kinoukr?rjson={rjson}&clarification={clarification}&title={enc_title}&original_title={enc_original_title}&year={year}&href={HttpUtility.UrlEncode(similar.href)}"; stpl.Append(similar.title, similar.year, string.Empty, link); } return stpl; } return default; } #endregion if (result.source_type == "ashdi") { var invk = new AshdiInvoke(host, apihost, http, onstreamfile, requesterror: requesterror); int.TryParse(t, out int _t); var md = new Models.Online.Ashdi.EmbedModel() { content = result.content, serial = result.serial_ashdi }; return invk.Tpl(md, 0, title, original_title, _t, s, vast, rjson, host + $"lite/kinoukr?rjson={rjson}&clarification={clarification}&title={enc_title}&original_title={enc_original_title}&year={year}&href={enc_href}"); } if (result.content != null) { #region Фильм var mtpl = new MovieTpl(title, original_title, 1); string hls = Regex.Match(result.content, "file: ?(\"|')(?https?://[^\"']+/index\\.m3u8)(\"|')").Groups["hls"].Value; if (string.IsNullOrWhiteSpace(hls)) { string base64 = Regex.Match(result.content, "file: ?(\"|')(?[^\"']+)(\"|')").Groups["base64"].Value; base64 = Regex.Replace(base64, "==$", ""); hls = string.Join("", CrypTo.DecodeBase64(base64).Reverse()); if (string.IsNullOrWhiteSpace(hls)) return default; } #region subtitle var subtitles = new SubtitleTpl(); string subtitle = new Regex("\"subtitle\": ?\"([^\"]+)\"").Match(result.content).Groups[1].Value; if (!string.IsNullOrEmpty(subtitle)) { var match = new Regex("\\[([^\\]]+)\\](https?://[^\\,]+)").Match(subtitle); while (match.Success) { subtitles.Append(match.Groups[1].Value, onstreamfile.Invoke(match.Groups[2].Value)); match = match.NextMatch(); } } #endregion mtpl.Append(string.IsNullOrEmpty(result.quel) ? "По умолчанию" : result.quel, onstreamfile.Invoke(hls), subtitles: subtitles, vast: vast); return mtpl; #endregion } else { #region Сериал try { if (s == -1) { #region Сезоны var tpl = new SeasonTpl(); foreach (var season in result.serial) { string link = host + $"lite/kinoukr?rjson={rjson}&clarification={clarification}&title={enc_title}&original_title={enc_original_title}&year={year}&href={enc_href}&s={season.season}"; tpl.Append(season.title, link, season.season); } return tpl; #endregion } else { string sArhc = s.ToString(); var episodes = result.serial.First(i => i.season == sArhc).folder; #region Перевод var vtpl = new VoiceTpl(); var hashVoice = new HashSet(20); foreach (var episode in episodes) { foreach (var voice in episode.folder) { if (!hashVoice.Add(voice.title)) continue; if (string.IsNullOrEmpty(t)) t = voice.title; string link = host + $"lite/kinoukr?rjson={rjson}&clarification={clarification}&title={enc_title}&original_title={enc_original_title}&year={year}&href={enc_href}&s={s}&t={voice.title}"; vtpl.Append(voice.title, t == voice.title, link); } } #endregion var etpl = new EpisodeTpl(vtpl, episodes.Length); foreach (var episode in episodes) { var video = episode.folder.FirstOrDefault(i => i.title == t); if (video.file == null) continue; #region subtitle var subtitles = new SubtitleTpl(); if (!string.IsNullOrEmpty(video.subtitle)) { var match = new Regex("\\[([^\\]]+)\\](https?://[^\\,]+)").Match(video.subtitle); while (match.Success) { subtitles.Append(match.Groups[1].Value, onstreamfile.Invoke(match.Groups[2].Value)); match = match.NextMatch(); } } #endregion string file = onstreamfile.Invoke(video.file); etpl.Append(episode.title, title ?? original_title, sArhc, episode.number, file, subtitles: subtitles, vast: vast); } return etpl; } } catch { return default; } #endregion } } #endregion } }