This commit is contained in:
jack 2023-12-11 11:24:12 +07:00
parent 4cdfa5802d
commit 7f966fac10
13 changed files with 112 additions and 341 deletions

View file

@ -1,7 +1,7 @@
import org.jetbrains.kotlin.konan.properties.Properties
// use an integer for version numbers
version = 202
version = 203
android {
defaultConfig {

View file

@ -198,9 +198,10 @@ open class VCloud : ExtractorApi() {
val res = app.get(url)
val doc = res.document
val changedLink = doc.selectFirst("script:containsData(url =)")?.data()?.let {
"""url\s*=\s*['"](.*)['"];""".toRegex().find(it)?.groupValues?.get(1)
?.substringAfter("r=")
} ?: doc.selectFirst("div.div.vd.d-none a")?.attr("href")
val regex = """url\s*=\s*['"](.*)['"];""".toRegex()
val doc2 = app.get(regex.find(it)?.groupValues?.get(1) ?: return).text
regex.find(doc2)?.groupValues?.get(1)?.substringAfter("r=")
}
val header = doc.selectFirst("div.card-header")?.text()
app.get(
base64Decode(changedLink ?: return), cookies = res.cookies, headers = mapOf(
@ -208,7 +209,7 @@ open class VCloud : ExtractorApi() {
)
).document.select("p.text-success ~ a").apmap {
val link = it.attr("href")
if (link.contains("workers.dev")) {
if (link.contains("workers.dev") || it.text().contains("[Server : 1]")) {
callback.invoke(
ExtractorLink(
this.name,

View file

@ -2,6 +2,7 @@ package com.hexated
import com.hexated.AESGCM.decrypt
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.unixTime
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
@ -967,62 +968,50 @@ object SoraExtractor : SoraStream() {
title: String? = null,
year: Int? = null,
season: Int? = null,
lastSeason: Int? = null,
episode: Int? = null,
callback: (ExtractorLink) -> Unit
) {
val slug = title.createSlug()?.replace("-", " ")
val url = "$uhdmoviesAPI/?s=$slug"
var doc = app.get(url).document
if (doc.select("title").text() == "Just a moment...") {
doc = app.get(url, interceptor = CloudflareKiller()).document
}
val scriptData = doc.select("div.row.gridlove-posts article").map {
it.selectFirst("a")?.attr("href") to it.selectFirst("h1")?.text()
}
val fixTitle = title.createSlug()
val (seasonSlug, episodeSlug) = getEpisodeSlug(season, episode)
val detailUrl = (if (scriptData.size == 1) {
scriptData.first()
val url = if(season == null) {
"$uhdmoviesAPI/download-$fixTitle-$year"
} else {
scriptData.find { it.second?.filterMedia(title, year, lastSeason) == true }
})?.first
"$uhdmoviesAPI/download-$fixTitle"
}
val detailDoc = app.get(detailUrl ?: return).document
val detailDoc = app.get(url, interceptor = CloudflareKiller()).document
val iframeList = detailDoc.select("div.entry-content p").map { it }
.filter { it.text().filterIframe(season, lastSeason, year, title) }.mapNotNull {
if (season == null) {
it.text() to it.nextElementSibling()?.select("a")?.attr("href")
} else {
it.text() to it.nextElementSibling()?.select("a")?.find { child ->
child.select("span").text().equals("Episode $episode", true)
}?.attr("href")
}
}.filter { it.second?.contains(Regex("(https:)|(http:)")) == true }
val iSelector = if(season == null) {
"div.entry-content p:has(:matches($year))"
} else {
"div.entry-content p:has(:matches((?i)(?:S\\s*$seasonSlug|Season\\s*$seasonSlug)))"
}
val iframeList = detailDoc.select(iSelector).mapNotNull {
if (season == null) {
it.text() to it.nextElementSibling()?.select("a")?.attr("href")
} else {
it.text() to it.nextElementSibling()?.select("a")?.find { child ->
child.select("span").text().equals("Episode $episode", true)
}?.attr("href")
}
}.filter { it.first.contains(Regex("(2160p)|(1080p)")) }
iframeList.apmap { (quality, link) ->
val driveLink =
when {
link?.contains("oddfirm") == true -> bypassHrefli(link)
link?.contains("driveleech") == true -> bypassDriveleech(link)
else -> bypassTechmny(link ?: return@apmap)
}
val driveLink = bypassHrefli(link ?: return@apmap)
val base = getBaseUrl(driveLink ?: return@apmap)
val driveReq = app.get(driveLink)
val driveRes = driveReq.document
val bitLink = driveRes.select("a.btn.btn-outline-success").attr("href")
val insLink =
driveRes.select("a.btn.btn-danger:contains(Instant Download)").attr("href")
val insLink = driveRes.select("a.btn.btn-danger:contains(Instant Download)").attr("href")
val downloadLink = when {
insLink.isNotEmpty() -> extractInstantUHD(insLink)
driveRes.select("button.btn.btn-success").text()
.contains("Direct Download", true) -> extractDirectUHD(driveLink, driveReq)
bitLink.isNullOrEmpty() -> {
val backupIframe = driveRes.select("a.btn.btn-outline-warning").attr("href")
extractBackupUHD(backupIframe ?: return@apmap)
}
else -> {
extractMirrorUHD(bitLink, base)
}
@ -1040,10 +1029,7 @@ object SoraExtractor : SoraStream() {
qualities
)
)
}
}
suspend fun invokeDotmovies(
@ -1113,34 +1099,32 @@ object SoraExtractor : SoraStream() {
val hTag = if (season == null) "h5" else "h3"
val aTag = if (season == null) "Download Now" else "V-Cloud"
val sTag = if (season == null) "" else "(Season $season|S$seasonSlug)"
res.select("div.entry-content > $hTag:matches((?i)$sTag.*(1080p|2160p))")
.filter { element -> !element.text().contains("Download", true) }.apmap {
val tags =
"""(?:1080p|2160p)(.*)""".toRegex().find(it.text())?.groupValues?.get(1)?.trim()
val href =
it.nextElementSibling()?.select("a:contains($aTag)")?.attr("href")?.let { url ->
app.post(
"${getBaseUrl(url)}/red.php",
data = mapOf("link" to url),
referer = "$api/"
).text.substringAfter("location.href = \"").substringBefore("\"")
}
val selector =
if (season == null) "p a:contains(V-Cloud)" else "h4:matches(0?$episode) + p a:contains(V-Cloud)"
val server =
app.get(
href ?: return@apmap
).document.selectFirst("div.entry-content > $selector")
?.attr("href")
loadCustomTagExtractor(
tags,
server ?: return@apmap,
"$api/",
subtitleCallback,
callback,
getIndexQuality(it.text())
val entry = res.select("div.entry-content > $hTag:matches((?i)$sTag.*(1080p|2160p))")
.findLast { element -> !element.text().contains("Download", true) } ?: return
val tags =
"""(?:1080p|2160p)(.*)""".toRegex().find(entry.text())?.groupValues?.get(1)?.trim()
val href =
entry.nextElementSibling()?.select("a:contains($aTag)")?.attr("href")
val selector =
if (season == null) "p a:contains(V-Cloud)" else "h4:matches(0?$episode) + p a:contains(V-Cloud)"
val serverRes = app.get(
href ?: return, interceptor = CloudflareKiller()
).document
val server = serverRes.selectFirst("div.entry-content > $selector")
?.attr("href")
loadExtractor(server ?: return, "$api/", subtitleCallback) { link ->
callback.invoke(
ExtractorLink(
link.name,
"${link.name} $tags",
link.url,
link.referer,
getIndexQuality(entry.text()),
link.type,
link.headers,
)
}
)
}
}
suspend fun invokeHdmovies4u(
@ -2210,10 +2194,12 @@ object SoraExtractor : SoraStream() {
"$cinemaTvAPI/shows/play/$id-$slug-$year"
}
val specialCookies = "PHPSESSID=e555h63ilisoj2l6j7b5d4jb6p; _csrf=9597150e45f485ad9c4f2e06a2572534d8415337eda9d48d0ecfa25b73b6a9e1a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%222HcnegjGB0nX205FAUPb86fqMx9HWIF1%22%3B%7D; _ga=GA1.1.1195498587.1701871187; _ga_VZD7HJ3WK6=GS1.1.$unixTime.4.0.1.$unixTime.0.0.0"
getCinemaChecker(specialCookies)
val headers = mapOf(
"Cookie" to "PHPSESSID=e555h63ilisoj2l6j7b5d4jb6p; _csrf=9597150e45f485ad9c4f2e06a2572534d8415337eda9d48d0ecfa25b73b6a9e1a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%222HcnegjGB0nX205FAUPb86fqMx9HWIF1%22%3B%7D; _ga=GA1.1.1195498587.1701871187; _ga_VZD7HJ3WK6=GS1.1.$unixTimeMS.4.0.1.$unixTimeMS.0.0.0",
"Cookie" to specialCookies,
"Connection" to "keep-alive",
"x-requested-with" to "com.wwcinematv",
"x-requested-with" to "XMLHttpRequest",
)
val doc = app.get(url, headers = headers).document

View file

@ -116,8 +116,8 @@ open class SoraStream : TmdbProvider() {
const val uhdmoviesAPI = "https://uhdmovies.zip"
const val gMoviesAPI = "https://gdrivemovies.xyz"
const val hdmovies4uAPI = "https://hdmovies4u.band"
const val vegaMoviesAPI = "https://vegamovies.ec"
const val dotmoviesAPI = "https://dotmovies.tokyo"
const val vegaMoviesAPI = "https://vegamovies.dad"
const val dotmoviesAPI = "https://dotmovies.bet"
const val tvMoviesAPI = "https://www.tvseriesnmovies.com"
const val moviezAddAPI = "https://ww3.moviezaddiction.click"
const val bollyMazaAPI = "https://ww3.bollymaza.click"
@ -467,7 +467,6 @@ open class SoraStream : TmdbProvider() {
res.title,
res.year,
res.season,
res.lastSeason,
res.episode,
callback
)

View file

@ -8,7 +8,6 @@ import com.hexated.SoraStream.Companion.filmxyAPI
import com.hexated.SoraStream.Companion.gdbot
import com.hexated.SoraStream.Companion.hdmovies4uAPI
import com.hexated.SoraStream.Companion.malsyncAPI
import com.hexated.SoraStream.Companion.smashyStreamAPI
import com.hexated.SoraStream.Companion.tvMoviesAPI
import com.hexated.SoraStream.Companion.watchflxAPI
import com.lagradost.cloudstream3.*
@ -34,8 +33,6 @@ import java.security.*
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
@ -47,6 +44,7 @@ import kotlin.math.min
var watchflxCookies: Map<String, String>? = null
var filmxyCookies: Map<String, String>? = null
var sfServer: String? = null
var cinemaTvChecker: Boolean? = null
val encodedIndex = arrayOf(
"GamMovies",
@ -95,52 +93,6 @@ val mimeType = arrayOf(
"video/x-msvideo"
)
fun String.filterIframe(
seasonNum: Int? = null,
lastSeason: Int? = null,
year: Int?,
title: String?
): Boolean {
val slug = title.createSlug()
val dotSlug = slug?.replace("-", ".")
val spaceSlug = slug?.replace("-", " ")
return if (seasonNum != null) {
if (lastSeason == 1) {
this.contains(Regex("(?i)(S0?$seasonNum)|(Season\\s0?$seasonNum)|(\\d{3,4}p)")) && !this.contains(
"Download",
true
)
} else {
this.contains(Regex("(?i)(S0?$seasonNum)|(Season\\s0?$seasonNum)")) && !this.contains(
"Download",
true
)
}
} else {
this.contains(Regex("(?i)($year)|($dotSlug)|($spaceSlug)")) && !this.contains(
"Download",
true
)
}
}
fun String.filterMedia(title: String?, yearNum: Int?, seasonNum: Int?): Boolean {
val fixTitle = title.createSlug()?.replace("-", " ")
return if (seasonNum != null) {
when {
seasonNum > 1 -> this.contains(Regex("(?i)(Season\\s0?1-0?$seasonNum)|(S0?1-S?0?$seasonNum)")) && this.contains(
Regex("(?i)($fixTitle)|($title)")
)
else -> this.contains(Regex("(?i)(Season\\s0?1)|(S0?1)")) && this.contains(
Regex("(?i)($fixTitle)|($title)")
) && this.contains("$yearNum")
}
} else {
this.contains(Regex("(?i)($fixTitle)|($title)")) && this.contains("$yearNum")
}
}
fun Document.getMirrorLink(): String? {
return this.select("div.mb-4 a").randomOrNull()
?.attr("href")
@ -632,28 +584,27 @@ suspend fun bypassFdAds(url: String?): String? {
}
suspend fun bypassHrefli(url: String): String? {
val postUrl = url.substringBefore("?id=").substringAfter("/?")
val res = app.post(
postUrl, data = mapOf(
"_wp_http" to url.substringAfter("?id=")
)
).document
fun Document.getFormUrl() : String {
return this.select("form#landing").attr("action")
}
fun Document.getFormData() : Map<String,String> {
return this.select("form#landing input").associate { it.attr("name") to it.attr("value") }
}
val link = res.select("form#landing").attr("action")
val wpHttp = res.select("input[name=_wp_http2]").attr("value")
val token = res.select("input[name=token]").attr("value")
val host = getBaseUrl(url)
var res = app.get(url).document
var formUrl = res.getFormUrl()
var formData = res.getFormData()
val blogRes = app.post(
link, data = mapOf(
"_wp_http2" to wpHttp,
"token" to token
)
).text
res = app.post(formUrl, data = formData).document
formUrl = res.getFormUrl()
formData = res.getFormData()
val skToken = blogRes.substringAfter("?go=").substringBefore("\"")
res = app.post(formUrl, data = formData).document
val skToken = res.selectFirst("script:containsData(?go=)")?.data()?.substringAfter("?go=")?.substringBefore("\"") ?: return null
val driveUrl = app.get(
"$postUrl?go=$skToken", cookies = mapOf(
skToken to wpHttp
"$host?go=$skToken", cookies = mapOf(
skToken to "${formData["_wp_http2"]}"
)
).document.selectFirst("meta[http-equiv=refresh]")?.attr("content")?.substringAfter("url=")
val path = app.get(driveUrl ?: return null).text.substringAfter("replace(\"")
@ -662,94 +613,6 @@ suspend fun bypassHrefli(url: String): String? {
return fixUrl(path, getBaseUrl(driveUrl))
}
suspend fun bypassTechmny(url: String): String? {
val techRes = app.get(url).document
val postUrl = url.substringBefore("?id=").substringAfter("/?")
val (goUrl, goHeader) = if (techRes.selectFirst("form#landing input[name=_wp_http_c]") != null) {
var res = app.post(
postUrl, data = mapOf(
"_wp_http_c" to url.substringAfter("?id=")
)
)
val (longC, catC, _) = getTechmnyCookies(res.text)
var headers = mapOf("Cookie" to "$longC; $catC")
var formLink = res.document.selectFirst("center a")?.attr("href")
res = app.get(formLink ?: return null, headers = headers)
val (longC2, _, postC) = getTechmnyCookies(res.text)
headers = mapOf("Cookie" to "$catC; $longC2; $postC")
formLink = res.document.selectFirst("center a")?.attr("href")
res = app.get(formLink ?: return null, headers = headers)
val goToken = res.text.substringAfter("?go=").substringBefore("\"")
val tokenUrl = "$postUrl?go=$goToken"
val newLongC = "$goToken=" + longC2.substringAfter("=")
headers = mapOf("Cookie" to "$catC; rdst_post=; $newLongC")
Pair(tokenUrl, headers)
} else {
val secondPage = techRes.getNextTechPage().document
val thirdPage = secondPage.getNextTechPage().text
val goToken = thirdPage.substringAfter("?go=").substringBefore("\"")
val tokenUrl = "$postUrl?go=$goToken"
val headers = mapOf(
"Cookie" to "$goToken=${
secondPage.select("form#landing input[name=_wp_http2]").attr("value")
}"
)
Pair(tokenUrl, headers)
}
val driveUrl =
app.get(goUrl, headers = goHeader).document.selectFirst("meta[http-equiv=refresh]")
?.attr("content")?.substringAfter("url=")
val path = app.get(driveUrl ?: return null).text.substringAfter("replace(\"")
.substringBefore("\")")
if (path == "/404") return null
return fixUrl(path, getBaseUrl(driveUrl))
}
private suspend fun Document.getNextTechPage(): NiceResponse {
return app.post(
this.select("form").attr("action"),
data = this.select("form input").mapNotNull {
it.attr("name") to it.attr("value")
}.toMap().toMutableMap()
)
}
suspend fun bypassDriveleech(url: String): String? {
val path = app.get(url).text.substringAfter("replace(\"")
.substringBefore("\")")
if (path == "/404") return null
return fixUrl(path, getBaseUrl(url))
}
private fun getTechmnyCookies(page: String): Triple<String, String, String> {
val cat = "rdst_cat"
val post = "rdst_post"
val longC = page.substringAfter(".setTime")
.substringAfter("document.cookie = \"")
.substringBefore("\"")
.substringBefore(";")
val catC = if (page.contains("$cat=")) {
page.substringAfterLast("$cat=")
.substringBefore(";").let {
"$cat=$it"
}
} else {
""
}
val postC = if (page.contains("$post=")) {
page.substringAfterLast("$post=")
.substringBefore(";").let {
"$post=$it"
}
} else {
""
}
return Triple(longC, catC, postC)
}
suspend fun getTvMoviesServer(url: String, season: Int?, episode: Int?): Pair<String, String?>? {
val req = app.get(url)
@ -780,6 +643,16 @@ suspend fun getTvMoviesServer(url: String, season: Int?, episode: Int?): Pair<St
}
}
suspend fun getCinemaChecker(cookie: String) = cinemaTvChecker ?: fetchCinemaChecker(cookie).also { cinemaTvChecker = it }
suspend fun fetchCinemaChecker(cookie: String): Boolean? {
return app.post(
base64Decode("aHR0cHM6Ly9jaW5lbWEud2l3aWNlbnRlci5jb20vYXBpL3YxL2Nvb2tpZQ=="),
data = mapOf("cookie" to cookie),
headers = mapOf("App-version" to "3.4", "Authorization" to "Basic d2l3aTpXaXdpQDIwMjA=")
).parsedSafe<Map<String,Boolean?>>()?.get("success")
}
suspend fun getSfServer() = sfServer ?: fetchSfServer().also { sfServer = it }
suspend fun fetchSfServer(): String {
@ -1410,7 +1283,7 @@ private enum class Symbol(val decimalValue: Int) {
companion object {
fun closestBelow(value: Int) =
values()
entries.toTypedArray()
.sortedByDescending { it.decimalValue }
.firstOrNull { value >= it.decimalValue }
}