lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

463 lines
17 KiB
C#

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<RezkaSettings>
{
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<ActionResult> 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<br>{init.host}/payments/");
if (requestInfo.Country == "RU")
{
if (rch.InfoConnected()?.rchtype != "apk")
return ShowError($"Нужен HDRezka Premium<br>{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<SearchModel>($"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<ActionResult> 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<ActionResult> 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<string, CookieContainer> cookieContainer = new ();
async ValueTask<CookieContainer> 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<string, string>
{
{ "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<string, string> 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
}
}