431 lines
16 KiB
C#
431 lines
16 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Shared.Models.Online.Rezka;
|
|
using Shared.Models.Online.Settings;
|
|
using System.Management;
|
|
using System.Net;
|
|
|
|
namespace Online.Controllers
|
|
{
|
|
public class RezkaPremium : BaseOnlineController<RezkaSettings>
|
|
{
|
|
#region InitRezkaInvoke
|
|
static string uid = null, typeuid = null;
|
|
|
|
(RezkaInvoke invk, string cookie, string log) onrezka;
|
|
|
|
public RezkaPremium() : base(AppInit.conf.RezkaPrem)
|
|
{
|
|
#region genUid
|
|
if (uid == null)
|
|
{
|
|
try
|
|
{
|
|
uid = System.IO.File.ReadAllText("/etc/machine-id");
|
|
typeuid = "machine-id";
|
|
}
|
|
catch
|
|
{
|
|
if (AppInit.Win32NT)
|
|
{
|
|
try
|
|
{
|
|
using (var searcher = new ManagementObjectSearcher("select ProcessorId from Win32_Processor"))
|
|
{
|
|
foreach (var item in searcher.Get())
|
|
uid = item["ProcessorId"].ToString();
|
|
}
|
|
|
|
typeuid = "ProcessorId";
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(uid))
|
|
{
|
|
if (System.IO.File.Exists("cache/uid"))
|
|
{
|
|
uid = System.IO.File.ReadAllText("cache/uid");
|
|
}
|
|
else
|
|
{
|
|
uid = CrypTo.SHA256(DateTime.Now.ToBinary().ToString());
|
|
System.IO.File.WriteAllText("cache/uid", uid);
|
|
}
|
|
|
|
typeuid = "generate";
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
loadKitInitialization = (j, i, c) =>
|
|
{
|
|
if (j.ContainsKey("uacdn"))
|
|
i.uacdn = c.uacdn;
|
|
|
|
if (j.ContainsKey("forceua"))
|
|
i.forceua = c.forceua;
|
|
|
|
if (j.ContainsKey("reserve"))
|
|
i.reserve = c.reserve;
|
|
|
|
return i;
|
|
};
|
|
|
|
requestInitializationAsync = async () =>
|
|
{
|
|
init.host = new RezkaSettings(null, "kwwsv=22odps1df").host;
|
|
|
|
var cook = await getCookie(init);
|
|
if (string.IsNullOrEmpty(cook.cookie))
|
|
{
|
|
onrezka = (null, null, cook.log);
|
|
return;
|
|
}
|
|
|
|
var headers = apiHeaders(cook.cookie);
|
|
|
|
string country = requestInfo.Country;
|
|
|
|
if (rch != null && !rch.enable && country != null)
|
|
headers.Add(new HeadersModel("X-Real-IP", requestInfo.IP));
|
|
|
|
if (init.forceua)
|
|
country = "UA";
|
|
|
|
init.premium = true;
|
|
|
|
onrezka = (new RezkaInvoke
|
|
(
|
|
host,
|
|
"lite/rhsprem",
|
|
init,
|
|
true,
|
|
headers,
|
|
httpHydra,
|
|
streamfile => HostStreamProxy(RezkaInvoke.fixcdn(country, init.uacdn, streamfile)),
|
|
requesterror: () => proxyManager?.Refresh()
|
|
), cook.cookie, null);
|
|
};
|
|
}
|
|
|
|
List<HeadersModel> apiHeaders(string cookie)
|
|
{
|
|
var headers = httpHeaders(init, HeadersModel.Init(
|
|
("X-Lampac-App", "1"),
|
|
("X-Lampac-Version", $"{appversion}.{minorversion}"),
|
|
("X-Lampac-Device-Id", $"{(AppInit.Win32NT ? "win32" : "linux")}:uid/{Regex.Replace(uid, "[^a-zA-Z0-9]+", "").Trim()}:type_uid/{typeuid}"),
|
|
("X-Lampac-Cookie", cookie)
|
|
));
|
|
|
|
if (!init.rhub)
|
|
headers.Add(new HeadersModel("User-Agent", requestInfo.UserAgent));
|
|
|
|
return headers;
|
|
}
|
|
#endregion
|
|
|
|
#region RezkaBind
|
|
[HttpGet]
|
|
[AllowAnonymous]
|
|
[Route("/lite/rhs/bind")]
|
|
async public Task<ActionResult> RezkaBind(string login, string pass)
|
|
{
|
|
string html = string.Empty;
|
|
|
|
if (string.IsNullOrWhiteSpace(login) || string.IsNullOrWhiteSpace(pass))
|
|
{
|
|
html = "Введите данные аккаунта rezka.ag <br> <br><form method=\"get\" action=\"/lite/rhs/bind\"><input type=\"text\" name=\"login\" placeholder=\"email\"> <input type=\"text\" name=\"pass\" placeholder=\"пароль\"><br><br><button>Авторизоваться</button></form> ";
|
|
}
|
|
else
|
|
{
|
|
var result = await getCookie(new RezkaSettings(null, "kwwsv=22odps1df")
|
|
{
|
|
login = login,
|
|
passwd = pass
|
|
}, timeoutError: 5);
|
|
|
|
if (string.IsNullOrEmpty(result.cookie))
|
|
{
|
|
html = "Ошибка авторизации ;(<br><br>" + result.log.Replace("\n", "<br>");
|
|
}
|
|
else
|
|
{
|
|
html = "Добавьте в init.conf<br><br>\"RezkaPrem\": {<br> \"enable\": true,<br> \"cookie\": \"" + result.cookie + "\"<br>},<br>\"Rezka\": {<br> \"enable\": false<br>}";
|
|
}
|
|
}
|
|
|
|
return ContentTo(html);
|
|
}
|
|
#endregion
|
|
|
|
[HttpGet]
|
|
[Route("lite/rhsprem")]
|
|
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))
|
|
return badInitMsg;
|
|
|
|
if (string.IsNullOrEmpty(href) && !string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(id))
|
|
{
|
|
if (source.Equals("rezka", StringComparison.OrdinalIgnoreCase) ||
|
|
source.Equals("hdrezka", StringComparison.OrdinalIgnoreCase))
|
|
href = id;
|
|
}
|
|
|
|
if (rch?.enable == true && string.IsNullOrEmpty(init.cookie))
|
|
return ShowError($"rhub работает через cookie - {host}/lite/rhs/bind");
|
|
|
|
if (string.IsNullOrWhiteSpace(href) && string.IsNullOrWhiteSpace(title))
|
|
return OnError("href/title = null");
|
|
|
|
if (onrezka.invk == null)
|
|
return OnError("authorization error ;(", weblog: onrezka.log);
|
|
|
|
var oninvk = onrezka.invk;
|
|
|
|
#region search
|
|
string search_uri = null;
|
|
|
|
if (string.IsNullOrEmpty(href))
|
|
{
|
|
var search = await InvokeCacheResult<SearchModel>($"rhsprem: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/rhsprem?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($"rhsprem:{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/rhsprem/serial")]
|
|
async public Task<ActionResult> Serial(string title, string original_title, string href, long id, int t, int s = -1, bool rjson = false, bool similar = false)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(href))
|
|
return OnError("href = null");
|
|
|
|
if (await IsRequestBlocked(rch: true))
|
|
return badInitMsg;
|
|
|
|
if (onrezka.invk == null)
|
|
return OnError("authorization error ;(", weblog: onrezka.log);
|
|
|
|
var oninvk = onrezka.invk;
|
|
|
|
var cache_root = await InvokeCacheResult($"rhsprem:view:serial:{id}:{t}", 20,
|
|
() => oninvk.SerialEmbed(id, t)
|
|
);
|
|
|
|
var cache_content = await InvokeCacheResult($"rhsprem:{href}", 10,
|
|
() => oninvk.Embed(href, null)
|
|
);
|
|
|
|
if (!cache_content.IsSuccess)
|
|
return OnError();
|
|
|
|
if (cache_content?.Value?.IsEmpty == true)
|
|
return ShowError(cache_content.Value.content);
|
|
|
|
return await ContentTpl(oninvk.Serial(cache_root.Value, cache_content.Value, accsArgs(string.Empty), title, original_title, href, id, t, s, true, rjson));
|
|
}
|
|
#endregion
|
|
|
|
#region Movie
|
|
[HttpGet]
|
|
[Route("lite/rhsprem/movie")]
|
|
[Route("lite/rhsprem/movie.m3u8")]
|
|
async public ValueTask<ActionResult> Movie(string title, string original_title, 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 (onrezka.invk == null)
|
|
return OnError("authorization error ;(", weblog: onrezka.log);
|
|
|
|
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);
|
|
}
|
|
|
|
var oninvk = onrezka.invk;
|
|
|
|
var cache = await InvokeCacheResult($"rhsprem:view:get_cdn_series:{id}:{t}:{director}:{s}:{e}:{onrezka.cookie}", 5,
|
|
() => oninvk.Movie(id, t, director, s, e, favs)
|
|
);
|
|
|
|
string result = oninvk.Movie(cache.Value, title, original_title, play, vast: init.vast);
|
|
if (result == null)
|
|
return OnError("result = null", weblog: oninvk.requestlog);
|
|
|
|
if (play)
|
|
return RedirectToPlay(result);
|
|
|
|
return ContentTo(result.Replace("/rezka", "/rhsprem"));
|
|
}
|
|
#endregion
|
|
|
|
|
|
#region getCookie
|
|
static Dictionary<string, string> authCookie = new Dictionary<string, string>();
|
|
|
|
async ValueTask<(string cookie, string log)> getCookie(RezkaSettings init, int timeoutError = 15)
|
|
{
|
|
if (!string.IsNullOrEmpty(init.cookie))
|
|
return ($"dle_user_taken=1; {Regex.Match(init.cookie, "(dle_user_id=[^;]+;)")} {Regex.Match(init.cookie, "(dle_password=[^;]+)")}".Trim(), null);
|
|
|
|
if (string.IsNullOrEmpty(init.login) || string.IsNullOrEmpty(init.passwd))
|
|
return default;
|
|
|
|
if (authCookie.TryGetValue(init.login, out string _cook))
|
|
return (_cook, null);
|
|
|
|
if (memoryCache.TryGetValue($"rhsprem:login:{init.login}", out _))
|
|
return default;
|
|
|
|
string loglines = string.Empty;
|
|
memoryCache.Set($"rhsprem:login:{init.login}", 0, TimeSpan.FromSeconds(timeoutError));
|
|
|
|
try
|
|
{
|
|
using (var clientHandler = new System.Net.Http.HttpClientHandler()
|
|
{
|
|
AllowAutoRedirect = false,
|
|
AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip | DecompressionMethods.Deflate
|
|
})
|
|
{
|
|
|
|
if (proxy != null)
|
|
{
|
|
clientHandler.UseProxy = true;
|
|
clientHandler.Proxy = proxy;
|
|
}
|
|
else { clientHandler.UseProxy = false; }
|
|
|
|
clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
|
|
using (var client = new System.Net.Http.HttpClient(clientHandler))
|
|
{
|
|
client.Timeout = TimeSpan.FromSeconds(15);
|
|
|
|
foreach (var item in apiHeaders(string.Empty))
|
|
client.DefaultRequestHeaders.Add(item.name, item.val);
|
|
|
|
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))
|
|
{
|
|
loglines += $"POST: {init.host}/ajax/login/\n";
|
|
loglines += $"{postContent.ReadAsStringAsync().Result}\n";
|
|
|
|
using (var response = await client.PostAsync($"{init.host}/ajax/login/", postContent))
|
|
{
|
|
loglines += $"\n\nStatusCode: {(int)response.StatusCode}\n";
|
|
|
|
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;"))
|
|
continue;
|
|
|
|
loglines += $"Set-Cookie: {line}\n";
|
|
|
|
if (line.Contains("dle_user_id") || line.Contains("dle_password"))
|
|
cookie += $"{line.Split(";")[0]}; ";
|
|
}
|
|
|
|
if (cookie.Contains("dle_user_id") && cookie.Contains("dle_password"))
|
|
{
|
|
_cook = $"dle_user_taken=1; {Regex.Replace(cookie.Trim(), ";$", "")}";
|
|
authCookie.TryAdd(init.login, _cook);
|
|
}
|
|
|
|
loglines += $"authCookie: {authCookie}\n\n";
|
|
loglines += await response.Content.ReadAsStringAsync();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex) { loglines += $"\n\nHDRezka Exception: {ex}"; }
|
|
|
|
return (_cook, loglines);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|