lampac/Shared/Engine/SISI/HQpornerTo.cs
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

538 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Shared.Engine.RxEnumerate;
using Shared.Models.SISI.Base;
using System.Text;
using System.Threading;
using System.Web;
namespace Shared.Engine.SISI
{
public static class HQpornerTo
{
static readonly ThreadLocal<StringBuilder> sbUri = new(() => new StringBuilder(PoolInvk.rentChunk));
#region Uri
public static string Uri(string host, string search, string sort, string c, int pg)
{
var url = sbUri.Value;
url.Clear();
url.Append(host);
url.Append("/");
if (!string.IsNullOrWhiteSpace(search))
{
url.Append($"?q={HttpUtility.UrlEncode(search)}&p={pg}");
}
else
{
if (!string.IsNullOrEmpty(c))
{
url.Append($"category/{c}");
}
else
{
if (!string.IsNullOrEmpty(sort))
url.Append($"top/{sort}");
else
url.Append("hdporn");
}
url.Append($"/{pg}");
}
return url.ToString();
}
#endregion
#region Playlist
public static List<PlaylistItem> Playlist(string uri, ReadOnlySpan<char> html, Func<PlaylistItem, PlaylistItem> onplaylist = null)
{
if (html.IsEmpty)
return null;
var rx = Rx.Split("<div class=\"img-container\">", html, 1);
if (rx.Count == 0)
return null;
var playlists = new List<PlaylistItem>(rx.Count);
foreach (var row in rx.Rows())
{
var g = row.Groups("href=\"/([^\"]+)\" class=\"atfi[^\"]+\"><img src=\"//([^\"]+)\"[^>]+ alt=\"([^\"]+)\"");
if (!string.IsNullOrWhiteSpace(g[1].Value) && !string.IsNullOrWhiteSpace(g[2].Value) && !string.IsNullOrWhiteSpace(g[3].Value))
{
var pl = new PlaylistItem()
{
name = g[3].Value.Trim(),
video = $"{uri}?uri={g[1].Value}",
picture = "https://" + g[2].Value,
time = row.Match("class=\"fa fa-clock-o\" [^>]+></i>([\n\r\t ]+)?([^<]+)<", 2, trim: true),
json = true,
bookmark = new Bookmark()
{
site = "hqr",
href = g[1].Value,
image = "https://" + g[2].Value
}
};
if (onplaylist != null)
pl = onplaylist.Invoke(pl);
playlists.Add(pl);
}
}
return playlists;
}
#endregion
#region Menu
public static List<MenuItem> Menu(string host, string sort, string c)
{
host = string.IsNullOrWhiteSpace(host) ? string.Empty : $"{host}/";
string url = host + "hqr";
var menu = new List<MenuItem>()
{
new MenuItem()
{
title = "Поиск",
search_on = "search_on",
playlist_url = url,
}
};
if (string.IsNullOrEmpty(c))
{
menu.Add(new MenuItem()
{
title = $"Сортировка: {(string.IsNullOrEmpty(sort) ? "новинки" : sort)}",
playlist_url = "submenu",
submenu = new List<MenuItem>()
{
new MenuItem()
{
title = "Самые новые",
playlist_url = url + $"?c={c}"
},
new MenuItem()
{
title = "Топ недели",
playlist_url = url + $"?c={c}&sort=week"
},
new MenuItem()
{
title = "Топ месяца",
playlist_url = url + $"?c={c}&sort=month"
}
}
});
}
{
var submenu = new List<MenuItem>()
{
new MenuItem()
{
title = "Все",
playlist_url = url + $"?sort={sort}"
},
new MenuItem()
{
title = "1080p porn",
playlist_url = url + $"?sort={sort}&c=1080p-porn"
},
new MenuItem()
{
title = "anal",
playlist_url = url + $"?sort={sort}&c=anal-sex-hd"
},
new MenuItem()
{
title = "4k porn",
playlist_url = url + $"?sort={sort}&c=4k-porn"
},
new MenuItem()
{
title = "milf",
playlist_url = url + $"?sort={sort}&c=milf"
},
new MenuItem()
{
title = "lesbian",
playlist_url = url + $"?sort={sort}&c=lesbian"
},
new MenuItem()
{
title = "60fps",
playlist_url = url + $"?sort={sort}&c=60fps-porn"
},
new MenuItem()
{
title = "creampie",
playlist_url = url + $"?sort={sort}&c=creampie"
},
new MenuItem()
{
title = "big tits",
playlist_url = url + $"?sort={sort}&c=big-tits"
},
new MenuItem()
{
title = "teen porn",
playlist_url = url + $"?sort={sort}&c=teen-porn"
},
new MenuItem()
{
title = "pov",
playlist_url = url + $"?sort={sort}&c=pov"
},
new MenuItem()
{
title = "threesome",
playlist_url = url + $"?sort={sort}&c=threesome"
},
new MenuItem()
{
title = "asian",
playlist_url = url + $"?sort={sort}&c=asian"
},
new MenuItem()
{
title = "old and young",
playlist_url = url + $"?sort={sort}&c=old-and-young"
},
new MenuItem()
{
title = "ebony",
playlist_url = url + $"?sort={sort}&c=ebony"
},
new MenuItem()
{
title = "big ass",
playlist_url = url + $"?sort={sort}&c=big-ass"
},
new MenuItem()
{
title = "interracial",
playlist_url = url + $"?sort={sort}&c=interracial"
},
new MenuItem()
{
title = "squirt",
playlist_url = url + $"?sort={sort}&c=squirt"
},
new MenuItem()
{
title = "mature",
playlist_url = url + $"?sort={sort}&c=mature"
},
new MenuItem()
{
title = "sex massage",
playlist_url = url + $"?sort={sort}&c=porn-massage"
},
new MenuItem()
{
title = "amateur",
playlist_url = url + $"?sort={sort}&c=amateur"
},
new MenuItem()
{
title = "casting",
playlist_url = url + $"?sort={sort}&c=casting"
},
new MenuItem()
{
title = "gangbang",
playlist_url = url + $"?sort={sort}&c=gangbang"
},
new MenuItem()
{
title = "stockings",
playlist_url = url + $"?sort={sort}&c=stockings"
},
new MenuItem()
{
title = "big dick",
playlist_url = url + $"?sort={sort}&c=big-dick"
},
new MenuItem()
{
title = "babe",
playlist_url = url + $"?sort={sort}&c=babe"
},
new MenuItem()
{
title = "latina",
playlist_url = url + $"?sort={sort}&c=latina"
},
new MenuItem()
{
title = "group sex",
playlist_url = url + $"?sort={sort}&c=group-sex"
},
new MenuItem()
{
title = "russian",
playlist_url = url + $"?sort={sort}&c=russian"
},
new MenuItem()
{
title = "masturbation",
playlist_url = url + $"?sort={sort}&c=masturbation"
},
new MenuItem()
{
title = "hairy pussy",
playlist_url = url + $"?sort={sort}&c=hairy-pussy"
},
new MenuItem()
{
title = "uniforms",
playlist_url = url + $"?sort={sort}&c=uniforms"
},
new MenuItem()
{
title = "shemale",
playlist_url = url + $"?sort={sort}&c=shemale"
},
new MenuItem()
{
title = "blonde",
playlist_url = url + $"?sort={sort}&c=blonde"
},
new MenuItem()
{
title = "orgasm",
playlist_url = url + $"?sort={sort}&c=orgasm"
},
new MenuItem()
{
title = "pickup",
playlist_url = url + $"?sort={sort}&c=pickup"
},
new MenuItem()
{
title = "sex party",
playlist_url = url + $"?sort={sort}&c=sex-parties"
},
new MenuItem()
{
title = "bdsm",
playlist_url = url + $"?sort={sort}&c=bdsm"
},
new MenuItem()
{
title = "public",
playlist_url = url + $"?sort={sort}&c=public"
},
new MenuItem()
{
title = "japanese",
playlist_url = url + $"?sort={sort}&c=japanese-girls-porn"
},
new MenuItem()
{
title = "redhead",
playlist_url = url + $"?sort={sort}&c=redhead"
},
new MenuItem()
{
title = "orgy",
playlist_url = url + $"?sort={sort}&c=orgy"
},
new MenuItem()
{
title = "blowjob",
playlist_url = url + $"?sort={sort}&c=blowjob"
},
new MenuItem()
{
title = "fetish",
playlist_url = url + $"?sort={sort}&c=fetish"
},
new MenuItem()
{
title = "brunette",
playlist_url = url + $"?sort={sort}&c=brunette"
},
new MenuItem()
{
title = "small tits",
playlist_url = url + $"?sort={sort}&c=small-tits"
},
new MenuItem()
{
title = "undressing",
playlist_url = url + $"?sort={sort}&c=undressing"
},
new MenuItem()
{
title = "cumshot",
playlist_url = url + $"?sort={sort}&c=cumshot"
},
new MenuItem()
{
title = "outdoor",
playlist_url = url + $"?sort={sort}&c=outdoor"
},
new MenuItem()
{
title = "deepthroat",
playlist_url = url + $"?sort={sort}&c=deepthroat"
},
new MenuItem()
{
title = "bondage",
playlist_url = url + $"?sort={sort}&c=bondage"
},
new MenuItem()
{
title = "shaved pussy",
playlist_url = url + $"?sort={sort}&c=shaved-pussy"
},
new MenuItem()
{
title = "bisexual",
playlist_url = url + $"?sort={sort}&c=bisexual"
},
new MenuItem()
{
title = "hentai",
playlist_url = url + $"?sort={sort}&c=hentai"
},
new MenuItem()
{
title = "handjob",
playlist_url = url + $"?sort={sort}&c=handjob"
},
new MenuItem()
{
title = "pussy licking",
playlist_url = url + $"?sort={sort}&c=pussy-licking"
},
new MenuItem()
{
title = "moaning",
playlist_url = url + $"?sort={sort}&c=moaning"
},
new MenuItem()
{
title = "fisting",
playlist_url = url + $"?sort={sort}&c=fisting"
},
new MenuItem()
{
title = "vintage",
playlist_url = url + $"?sort={sort}&c=vintage"
},
new MenuItem()
{
title = "tattooed",
playlist_url = url + $"?sort={sort}&c=tattooed"
},
new MenuItem()
{
title = "beach",
playlist_url = url + $"?sort={sort}&c=beach-porn"
},
new MenuItem()
{
title = "vibrator",
playlist_url = url + $"?sort={sort}&c=vibrator"
},
new MenuItem()
{
title = "fingering",
playlist_url = url + $"?sort={sort}&c=fingering"
},
new MenuItem()
{
title = "squeezing tits",
playlist_url = url + $"?sort={sort}&c=squeezing-tits"
},
new MenuItem()
{
title = "long hair",
playlist_url = url + $"?sort={sort}&c=long-hair"
}
};
menu.Add(new MenuItem()
{
title = $"Категория: {submenu.FirstOrDefault(i => i.playlist_url!.EndsWith($"&c={c}")).title ?? "все"}",
playlist_url = "submenu",
submenu = submenu
});
}
return menu;
}
#endregion
#region StreamLinks
async public static Task<Dictionary<string, string>> StreamLinks(HttpHydra http, string host, string uri)
{
if (string.IsNullOrWhiteSpace(uri))
return null;
string uriframe = null;
await http.GetSpan($"{host}/{uri}", html =>
{
uriframe = Rx.Match(html, "<iframe src=\"//([^/]+/video/[^/]+/)\"");
});
if (uriframe == null)
return null;
var stream_links = new Dictionary<string, string>(5);
await http.GetSpan($"https://{uriframe}", iframeHtml =>
{
foreach (var row in Rx.Matches("src=.\"([^\"]+)\" title=.\"([^\"]+)\"", iframeHtml).Rows())
{
var g = row.Groups("src=.\"([^\"]+)\" title=.\"([^\"]+)\"");
if (!string.IsNullOrWhiteSpace(g[1].Value) && !string.IsNullOrWhiteSpace(g[2].Value) && !g[2].Value.Contains("Default"))
stream_links.TryAdd(g[2].Value.Replace("\\", ""), $"https:{g[1].Value.Replace("\\", "")}");
}
if (stream_links.Count == 0)
{
string jw = Rx.Match(iframeHtml, "\\$\\(\"#jw\"\\)([^;]+)");
if (jw.Contains("replaceAll"))
{
var grpal = Rx.Groups(iframeHtml, "replaceAll\\(\"([^\"]+)\",([^\\+]+)\\+\"pubs/\"\\+([^\\+]+)");
string cdn = Rx.Match(iframeHtml, grpal[2].Value + "=\"([^\"]+)\"");
string hash = Rx.Match(iframeHtml, grpal[3].Value + "=\"([^\"]+)\"");
if (!string.IsNullOrEmpty(cdn) && !string.IsNullOrEmpty(hash))
{
foreach (var row in Rx.Matches("src=.?\"([^\"]+[0-9]+\\.mp4)\" title=.?\"([^\"]+)\"", iframeHtml).Rows())
{
var g = row.Groups("src=.?\"([^\"]+[0-9]+\\.mp4)\" title=.?\"([^\"]+)\"");
if (!string.IsNullOrWhiteSpace(g[1].Value) && !string.IsNullOrWhiteSpace(g[2].Value) && !g[2].Value.Contains("Default"))
{
string hls = g[1].Value.Replace(grpal[1].Value, $"https:{cdn}pubs/{hash}/");
if (hls.StartsWith("https:"))
stream_links.TryAdd(g[2].Value.Replace("\\", ""), hls.Replace("\\", ""));
}
}
}
}
}
});
return stream_links.Reverse().ToDictionary(k => k.Key, v => v.Value);
}
#endregion
}
}