using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Shared.Models.Online.Rezka; using Shared.Models.Online.Settings; using System.Net; namespace Online.Controllers { public class Rezka : BaseOnlineController { RezkaInvoke oninvk; public Rezka() : base(AppInit.conf.Rezka) { loadKitInitialization = (j, i, c) => { if (j.ContainsKey("premium")) i.premium = c.premium; if (j.ContainsKey("uacdn")) i.uacdn = c.uacdn; if (j.ContainsKey("forceua")) i.forceua = c.forceua; if (j.ContainsKey("reserve")) i.reserve = c.reserve; if (j.ContainsKey("ajax")) i.ajax = c.ajax; return i; }; requestInitializationAsync = async () => { string country = init.forceua ? "UA" : requestInfo.Country; var headers = httpHeaders(init); var cookie = init.rhub ? null : await getCookie(); string cookieRhub = init.rhub ? getRhubCookie() : null; if (rch?.enable == true && cookieRhub != null) headers.Add(new HeadersModel("Cookie", cookieRhub)); if (init.xapp) headers.Add(new HeadersModel("X-App-Hdrezka-App", "1")); if (init.xrealip) headers.Add(new HeadersModel("realip", requestInfo.IP)); oninvk = new RezkaInvoke ( host, "lite/rezka", init, cookie != null || cookieRhub != null, headers, httpHydra, streamfile => HostStreamProxy(RezkaInvoke.fixcdn(country, init.uacdn, streamfile), headers: RezkaInvoke.StreamProxyHeaders(init)), requesterror: () => proxyManager?.Refresh() ); }; } [HttpGet] [Route("lite/rezka")] async public Task Index(string title, string original_title, int clarification, int year, int s = -1, string href = null, bool rjson = false, int serial = -1, bool similar = false, string source = null, string id = null) { if (await IsRequestBlocked(rch: true, rch_check: false)) return badInitMsg; #region Initialization if (init.premium || AppInit.conf.RezkaPrem.enable) return ShowError("Замените Rezka на RezkaPrem в init.conf"); if (string.IsNullOrWhiteSpace(href) && string.IsNullOrWhiteSpace(title)) return OnError(); if (rch != null) { if (rch.IsNotConnected() || rch.IsRequiredConnected()) return ContentTo(rch.connectionMsg); if (rch.enable) { if (rch.IsNotSupportRchAccess("web", out string rch_error)) return ShowError($"Нужен HDRezka Premium
{init.host}/payments/"); if (requestInfo.Country == "RU") { if (rch.InfoConnected()?.rchtype != "apk") return ShowError($"Нужен HDRezka Premium
{init.host}/payments/"); if (await getCookie() == null) return ShowError("Укажите логин/пароль или cookie"); } } } #endregion if (string.IsNullOrEmpty(href) && !string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(id)) { if (source.Equals("rezka", StringComparison.OrdinalIgnoreCase) || source.Equals("hdrezka", StringComparison.OrdinalIgnoreCase)) href = id; } #region search string search_uri = null; if (string.IsNullOrEmpty(href)) { var search = await InvokeCacheResult($"rezka:search:{title}:{original_title}:{clarification}:{year}", 40, async e => { var content = await oninvk.Search(title, original_title, clarification, year); if (content.IsError) return e.Fail(string.Empty, refresh_proxy: true); if (content.IsEmpty) { if (rch.enable || content.content != null) return e.Fail(content.content ?? "content"); } return e.Success(content); }); if (search.ErrorMsg != null) return ShowError(string.IsNullOrEmpty(search.ErrorMsg) ? "поиск не дал результатов" : search.ErrorMsg); if (similar || string.IsNullOrEmpty(search.Value?.href)) { if (search.Value?.IsEmpty == true) return ShowError(search.Value.content ?? "поиск не дал результатов"); return await ContentTpl(search, () => { if (search.Value.similar == null) return default; var stpl = new SimilarTpl(search.Value.similar.Count); foreach (var similar in search.Value.similar) { string link = $"{host}/lite/rezka?rjson={rjson}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&href={HttpUtility.UrlEncode(similar.href)}"; stpl.Append(similar.title, similar.year, string.Empty, link, PosterApi.Size(similar.img)); } return stpl; }); } href = search.Value.href; search_uri = search.Value.search_uri; } #endregion var cache = await InvokeCacheResult($"rezka:{href}", 10, () => oninvk.Embed(href, search_uri) ); if (cache.Value?.IsEmpty == true) return ShowError(cache.Value.content); return await ContentTpl(cache, () => oninvk.Tpl(cache.Value, accsArgs(string.Empty), title, original_title, s, href, true, rjson) ); } #region Serial [HttpGet] [Route("lite/rezka/serial")] async public Task Serial(string title, string original_title, string href, long id, int t, int s = -1, bool rjson = false) { if (string.IsNullOrEmpty(href)) return OnError(); if (await IsRequestBlocked(rch: true)) return badInitMsg; Episodes root = await InvokeCache($"rezka:view:serial:{id}:{t}", 20, () => oninvk.SerialEmbed(id, t) ); if (root == null) return OnError(); var cache = await InvokeCache($"rezka:{href}", 20, () => oninvk.Embed(href, null) ); if (cache == null) return OnError(); if (cache.IsEmpty) return ShowError(cache.content); return await ContentTpl(oninvk.Serial(root, cache, accsArgs(string.Empty), title, original_title, href, id, t, s, true, rjson)); } #endregion #region Movie [HttpGet] [Route("lite/rezka/movie")] [Route("lite/rezka/movie.m3u8")] async public ValueTask Movie(string title, string original_title, string voice, long id, int t, int director = 0, int s = -1, int e = -1, string favs = null, bool play = false) { if (await IsRequestBlocked(rch: true, rch_check: false)) return badInitMsg; if (rch != null) { if (rch.IsNotConnected()) { if (init.rhub_fallback && play) rch.Disabled(); else return ContentTo(rch.connectionMsg); } if (!play && rch.IsRequiredConnected()) return ContentTo(rch.connectionMsg); } string realip = (init.xrealip && init.corseu) ? requestInfo.IP : ""; MovieModel md = null; /// ajax = true (get_cdn_series) /// ajax = false (movie | get_cdn_series) /// ajax = null (movie) if (init.ajax != null && init.ajax.Value == false && !string.IsNullOrEmpty(voice)) { md = await InvokeCache(ipkey($"rezka:movie:{voice}:{realip}:{init.cookie}"), 20, () => oninvk.Movie(voice) ); } if (md == null && init.ajax != null) { md = await InvokeCache(ipkey($"rezka:view:get_cdn_series:{id}:{t}:{director}:{s}:{e}:{realip}:{init.cookie}"), 20, () => oninvk.Movie(id, t, director, s, e, favs) ); } if (md?.links == null || md.links.Count == 0) return OnError(); string result = oninvk.Movie(md, title, original_title, play, vast: init.vast); if (result == null) return OnError(); if (play) return RedirectToPlay(result); return ContentTo(result); } #endregion #region getCookie static ConcurrentDictionary cookieContainer = new (); async ValueTask getCookie() { string keyCookie = $"{init.cookie}:{init.login}"; if (cookieContainer.TryGetValue(keyCookie, out CookieContainer _container)) return _container; string domain = Regex.Match(init.host, "https?://([^/]+)").Groups[1].Value; #region setCookieContainer void setCookieContainer(string coks) { var container = new CookieContainer(); if (coks != string.Empty && !coks.Contains("hdmbbs")) coks = $"hdmbbs=1; {coks}"; if (!coks.Contains("dle_user_taken")) coks = $"dle_user_taken=1; {coks}"; foreach (string line in coks.Split(";")) { if (string.IsNullOrEmpty(line) || !line.Contains("=")) continue; var g = Regex.Match(line.Trim(), "^([^=]+)=([^\n\r]+)").Groups; string name = g[1].Value.Trim(); string value = g[2].Value.Trim(); if (name is "CLID" or "MUID" or "_clck" or "_clsk") continue; if (name.StartsWith("_ym_")) continue; if (name == "hdmbbs") { container.Add(new Cookie() { Path = "/", Expires = DateTime.Today.AddYears(1), Domain = domain, Name = name, Value = value }); } else { container.Add(new Cookie() { Path = "/", Expires = name == "PHPSESSID" ? default : DateTime.Today.AddYears(1), Domain = $".{domain}", Name = name, Value = value, HttpOnly = true }); } } cookieContainer[keyCookie] = container; } #endregion if (!string.IsNullOrEmpty(init.cookie)) { setCookieContainer(init.cookie.Trim()); return cookieContainer[keyCookie]; } if (string.IsNullOrEmpty(init.login) || string.IsNullOrEmpty(init.passwd)) { setCookieContainer(string.Empty); return cookieContainer[keyCookie]; } if (memoryCache.TryGetValue("rezka:login", out _)) return null; memoryCache.Set("rezka:login", 0, TimeSpan.FromMinutes(2)); try { using (var clientHandler = new System.Net.Http.HttpClientHandler() { AllowAutoRedirect = false }) { clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; using (var client = new System.Net.Http.HttpClient(clientHandler)) { client.Timeout = TimeSpan.FromSeconds(20); foreach (var h in Http.defaultFullHeaders) client.DefaultRequestHeaders.TryAddWithoutValidation(h.Key, h.Value); var postParams = new Dictionary { { "login_name", init.login }, { "login_password", init.passwd }, { "login_not_save", "0" } }; using (var postContent = new System.Net.Http.FormUrlEncodedContent(postParams)) { using (var response = await client.PostAsync($"{init.host}/ajax/login/", postContent)) { if (response.Headers.TryGetValues("Set-Cookie", out var cook)) { string cookie = string.Empty; foreach (string line in cook) { if (string.IsNullOrEmpty(line)) continue; if (line.Contains("=deleted;") || !line.Contains(domain)) continue; string c = line.Split(";")[0]; if (c.Contains("=")) { string name = c.Split("=")[0]; if (cookie.Contains(name)) { cookie = Regex.Replace(cookie, $"{name}=[^;]+", $"{name}={c.Split("=")[1]}"); } else { cookie += $"{c}; "; } } } if (cookie.Contains("dle_user_id") && cookie.Contains("dle_password")) { setCookieContainer(cookie.Trim()); return cookieContainer[keyCookie]; } } } } } } } catch { } return null; } #endregion #region getRhubCookie static ConcurrentDictionary rhubCookies = new(); string getRhubCookie() { if (string.IsNullOrWhiteSpace(init.cookie)) return null; if (rhubCookies.TryGetValue(init.cookie, out string _cook)) return _cook; string rhubCookie = string.Empty; string domain = Regex.Match(init.host, "https?://([^/]+)").Groups[1].Value; foreach (string line in init.cookie.Split(";")) { if (string.IsNullOrEmpty(line) || !line.Contains("=")) continue; var g = Regex.Match(line.Trim(), "^([^=]+)=([^\n\r]+)").Groups; string name = g[1].Value.Trim(); string value = g[2].Value.Trim(); if (name is "CLID" or "MUID" or "_clck" or "_clsk") continue; if (name.StartsWith("_ym_")) continue; if (name != "PHPSESSID") rhubCookie += $"{name}={value}; "; } rhubCookie = Regex.Replace(rhubCookie.Trim(), ";$", ""); rhubCookies[init.cookie] = rhubCookie; return rhubCookie; } #endregion } }