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

@ -4,12 +4,9 @@ import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.network.CloudflareKiller
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.httpsify
import com.lagradost.cloudstream3.utils.loadExtractor
import okhttp3.Interceptor
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
@ -18,26 +15,12 @@ class AnimeIndoProvider : MainAPI() {
override var name = "AnimeIndo"
override val hasMainPage = true
override var lang = "id"
private val cloudflareKiller by lazy { CloudflareKiller() }
private val interceptor by lazy { CloudflareInterceptor(cloudflareKiller) }
override val supportedTypes = setOf(
TvType.Anime,
TvType.AnimeMovie,
TvType.OVA
)
class CloudflareInterceptor(private val cloudflareKiller: CloudflareKiller): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
val doc = Jsoup.parse(response.peekBody(1024 * 1024).string())
if (doc.select("title").text() == "Just a moment...") {
return cloudflareKiller.intercept(chain)
}
return response
}
}
companion object {
fun getType(t: String): TvType {
return if (t.contains("OVA", true) || t.contains("Special")) TvType.OVA
@ -66,8 +49,7 @@ class AnimeIndoProvider : MainAPI() {
page: Int,
request: MainPageRequest
): HomePageResponse {
val url = "$mainUrl/${request.data}/page/$page"
val document = app.get(url, interceptor = interceptor).document
val document = app.get("$mainUrl/${request.data}/page/$page").document
val home = document.select("main#main div.animposx").mapNotNull {
it.toSearchResult()
}
@ -101,7 +83,6 @@ class AnimeIndoProvider : MainAPI() {
return newAnimeSearchResponse(title, href, TvType.Anime) {
this.posterUrl = posterUrl
addSub(epNum)
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
@ -109,8 +90,7 @@ class AnimeIndoProvider : MainAPI() {
override suspend fun search(query: String): List<SearchResponse> {
val anime = mutableListOf<SearchResponse>()
(1..2).forEach { page ->
val link = "$mainUrl/page/$page/?s=$query"
val document = app.get(link, interceptor = interceptor).document
val document = app.get("$mainUrl/page/$page/?s=$query").document
val media = document.select(".site-main.relat > article").mapNotNull {
val title = it.selectFirst("div.title > h2")!!.ownText().trim()
val href = it.selectFirst("a")!!.attr("href")
@ -118,7 +98,6 @@ class AnimeIndoProvider : MainAPI() {
val type = getType(it.select("div.type").text().trim())
newAnimeSearchResponse(title, href, type) {
this.posterUrl = posterUrl
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
if(media.isNotEmpty()) anime.addAll(media)
@ -127,8 +106,7 @@ class AnimeIndoProvider : MainAPI() {
}
override suspend fun load(url: String): LoadResponse? {
val document = app.get(url, interceptor = interceptor).document
val document = app.get(url).document
val title = document.selectFirst("h1.entry-title")?.text()?.replace("Subtitle Indonesia", "")
?.trim() ?: return null
val poster = document.selectFirst("div.thumb > img[itemprop=image]")?.attr("src")
@ -168,7 +146,6 @@ class AnimeIndoProvider : MainAPI() {
addTrailer(trailer)
addMalId(tracker?.malId)
addAniListId(tracker?.aniId?.toIntOrNull())
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
@ -179,12 +156,12 @@ class AnimeIndoProvider : MainAPI() {
callback: (ExtractorLink) -> Unit
): Boolean {
val document = app.get(data, interceptor = interceptor).document
val document = app.get(data).document
document.select("div.itemleft > .mirror > option").mapNotNull {
fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src"))
}.apmap {
if (it.startsWith(mainUrl)) {
app.get(it, referer = "$mainUrl/", interceptor = interceptor).document.select("iframe").attr("src")
app.get(it, referer = "$mainUrl/").document.select("iframe").attr("src")
} else {
it
}

View file

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

View file

@ -6,7 +6,7 @@ import com.lagradost.cloudstream3.utils.httpsify
import com.lagradost.cloudstream3.utils.loadExtractor
class DutaMovie : Gomov() {
override var mainUrl = "https://boxoffice.dutamovie21.club"
override var mainUrl = "https://bioskop.dutamovie21.vip"
override var name = "DutaMovie"
override val mainPage = mainPageOf(
"category/box-office/page/%d/" to "Box Office",

View file

@ -3,7 +3,7 @@ package com.hexated
import com.lagradost.cloudstream3.mainPageOf
class Ngefilm : Gomov() {
override var mainUrl = "https://nge-film21.fun"
override var mainUrl = "https://nge-film21.pics"
override var name = "Ngefilm"
override val mainPage = mainPageOf(

View file

@ -9,7 +9,7 @@ import org.jsoup.nodes.Element
import java.net.URI
class Nodrakorid : Gomov() {
override var mainUrl = "https://no-drakor.xyz"
override var mainUrl = "https://nodra-kor.xyz"
override var name = "Nodrakorid"
override val mainPage = mainPageOf(

View file

@ -2,10 +2,7 @@ package com.hexated
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.network.CloudflareKiller
import com.lagradost.cloudstream3.utils.*
import okhttp3.Interceptor
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import java.net.URLDecoder
@ -17,24 +14,10 @@ class Minioppai : MainAPI() {
override var lang = "id"
override val hasDownloadSupport = true
override val hasQuickSearch = true
private val cloudflareKiller by lazy { CloudflareKiller() }
private val interceptor by lazy { CloudflareInterceptor(cloudflareKiller) }
override val supportedTypes = setOf(
TvType.NSFW,
)
class CloudflareInterceptor(private val cloudflareKiller: CloudflareKiller): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
val doc = Jsoup.parse(response.peekBody(1024 * 1024).string())
if (doc.select("title").text() == "Just a moment...") {
return cloudflareKiller.intercept(chain)
}
return response
}
}
companion object {
fun getStatus(t: String?): ShowStatus {
return when (t) {
@ -54,7 +37,7 @@ class Minioppai : MainAPI() {
page: Int,
request: MainPageRequest
): HomePageResponse {
val document = app.get("${request.data}/page/$page", interceptor = interceptor).document
val document = app.get("${request.data}/page/$page").document
val home = document.select("div.latest a").mapNotNull {
it.toSearchResult()
}
@ -84,7 +67,6 @@ class Minioppai : MainAPI() {
return newAnimeSearchResponse(title, href, TvType.NSFW) {
this.posterUrl = posterUrl
addSub(epNum)
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
@ -97,7 +79,6 @@ class Minioppai : MainAPI() {
"action" to "ts_ac_do_search",
"ts_ac_query" to query,
), headers = mapOf("X-Requested-With" to "XMLHttpRequest"),
interceptor = interceptor
).parsedSafe<SearchResponses>()?.post?.firstOrNull()?.all?.mapNotNull { item ->
newAnimeSearchResponse(
item.postTitle ?: "",
@ -105,13 +86,12 @@ class Minioppai : MainAPI() {
TvType.NSFW
) {
this.posterUrl = item.postImage
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
}
override suspend fun load(url: String): LoadResponse? {
val document = app.get(url, interceptor = interceptor).document
val document = app.get(url).document
val title = document.selectFirst("h1.entry-title")?.text()?.trim() ?: return null
val poster = fixUrlNull(document.selectFirst("div.limage img")?.attr("src"))
@ -137,7 +117,6 @@ class Minioppai : MainAPI() {
showStatus = status
plot = description
this.tags = tags
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
@ -147,7 +126,7 @@ class Minioppai : MainAPI() {
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
val document = app.get(data, interceptor = interceptor).document
val document = app.get(data).document
document.select("div.server ul.mirror li a").mapNotNull {
Jsoup.parse(base64Decode(it.attr("data-em"))).select("iframe").attr("src")
}.apmap { link ->

View file

@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.network.CloudflareKiller
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import org.jsoup.nodes.Element
@ -34,16 +33,11 @@ open class Movierulzhd : MainAPI() {
"episodes" to "Episode",
)
val interceptor = CloudflareKiller()
override suspend fun getMainPage(
page: Int,
request: MainPageRequest
): HomePageResponse {
var document = app.get("$mainUrl/${request.data}/page/$page").document
if (document.select("title").text() == "Just a moment...") {
document = app.get(request.data + page, interceptor = interceptor).document
}
val document = app.get("$mainUrl/${request.data}/page/$page").document
val home =
document.select("div.items.normal article, div#archive-content article, div.items.full article").mapNotNull {
it.toSearchResult()
@ -79,18 +73,12 @@ open class Movierulzhd : MainAPI() {
return newMovieSearchResponse(title, href, TvType.Movie) {
this.posterUrl = posterUrl
this.quality = quality
posterHeaders = interceptor.getCookieHeaders(mainUrl).toMap()
}
}
override suspend fun search(query: String): List<SearchResponse> {
val link = "$mainUrl/search/$query"
var document = app.get(link).document
if (document.select("title").text() == "Just a moment...") {
document = app.get(link, interceptor = interceptor).document
}
val document = app.get("$mainUrl/search/$query").document
return document.select("div.result-item").map {
val title =
it.selectFirst("div.title > a")!!.text().replace(Regex("\\(\\d{4}\\)"), "").trim()
@ -98,17 +86,13 @@ open class Movierulzhd : MainAPI() {
val posterUrl = it.selectFirst("img")!!.attr("src").toString()
newMovieSearchResponse(title, href, TvType.TvSeries) {
this.posterUrl = posterUrl
posterHeaders = interceptor.getCookieHeaders(mainUrl).toMap()
}
}
}
override suspend fun load(url: String): LoadResponse {
val request = app.get(url)
var document = request.document
if (document.select("title").text() == "Just a moment...") {
document = app.get(url, interceptor = interceptor).document
}
val document = request.document
directUrl = getBaseUrl(request.url)
val title =
document.selectFirst("div.data > h1")?.text()?.trim().toString()
@ -142,7 +126,6 @@ open class Movierulzhd : MainAPI() {
val recPosterUrl = it.selectFirst("img")?.imageFromElement()
newTvSeriesSearchResponse(recName, recHref, TvType.TvSeries) {
this.posterUrl = recPosterUrl
posterHeaders = interceptor.getCookieHeaders(url).toMap()
}
}
@ -187,7 +170,6 @@ open class Movierulzhd : MainAPI() {
addActors(actors)
this.recommendations = recommendations
addTrailer(trailer)
posterHeaders = interceptor.getCookieHeaders(url).toMap()
}
} else {
newMovieLoadResponse(title, url, TvType.Movie, url) {
@ -199,7 +181,6 @@ open class Movierulzhd : MainAPI() {
addActors(actors)
this.recommendations = recommendations
addTrailer(trailer)
posterHeaders = interceptor.getCookieHeaders(url).toMap()
}
}
}
@ -232,10 +213,7 @@ open class Movierulzhd : MainAPI() {
).parsed<ResponseHash>().embed_url
if (!source.contains("youtube")) loadCustomExtractor(source, "$directUrl/", subtitleCallback, callback)
} else {
var document = app.get(data).document
if (document.select("title").text() == "Just a moment...") {
document = app.get(data, interceptor = interceptor).document
}
val document = app.get(data).document
document.select("ul#playeroptionsul > li").map {
Triple(

View file

@ -4,13 +4,9 @@ import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.network.CloudflareKiller
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor
import okhttp3.Interceptor
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
class Samehadaku : MainAPI() {
@ -19,26 +15,12 @@ class Samehadaku : MainAPI() {
override val hasMainPage = true
override var lang = "id"
override val hasDownloadSupport = true
private val cloudflareKiller by lazy { CloudflareKiller() }
private val interceptor by lazy { CloudflareInterceptor(cloudflareKiller) }
override val supportedTypes = setOf(
TvType.Anime,
TvType.AnimeMovie,
TvType.OVA
)
class CloudflareInterceptor(private val cloudflareKiller: CloudflareKiller): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
val doc = Jsoup.parse(response.peekBody(1024 * 1024).string())
if (doc.select("title").text() == "Just a moment...") {
return cloudflareKiller.intercept(chain)
}
return response
}
}
companion object {
const val acefile = "https://acefile.co"
@ -69,7 +51,7 @@ class Samehadaku : MainAPI() {
val items = mutableListOf<HomePageList>()
if (request.name != "Episode Terbaru" && page <= 1) {
val doc = app.get(request.data, interceptor = interceptor).document
val doc = app.get(request.data).document
doc.select("div.widget_senction:not(:contains(Baca Komik))").forEach { block ->
val header = block.selectFirst("div.widget-title h3")?.ownText() ?: return@forEach
val home = block.select("div.animepost").mapNotNull {
@ -80,8 +62,7 @@ class Samehadaku : MainAPI() {
}
if (request.name == "Episode Terbaru") {
val home =
app.get(request.data + page, interceptor = interceptor).document.selectFirst("div.post-show")?.select("ul li")
val home = app.get(request.data + page).document.selectFirst("div.post-show")?.select("ul li")
?.mapNotNull {
it.toSearchResult()
} ?: throw ErrorLoadingException("No Media Found")
@ -101,13 +82,12 @@ class Samehadaku : MainAPI() {
return newAnimeSearchResponse(title, href ?: return null, TvType.Anime) {
this.posterUrl = posterUrl
addSub(epNum)
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
override suspend fun search(query: String): List<SearchResponse> {
val document = app.get("$mainUrl/?s=$query", interceptor = interceptor).document
val document = app.get("$mainUrl/?s=$query").document
return document.select("main#main div.animepost").mapNotNull {
it.toSearchResult()
}
@ -117,10 +97,10 @@ class Samehadaku : MainAPI() {
val fixUrl = if (url.contains("/anime/")) {
url
} else {
app.get(url, interceptor = interceptor).document.selectFirst("div.nvs.nvsc a")?.attr("href")
app.get(url).document.selectFirst("div.nvs.nvsc a")?.attr("href")
}
val document = app.get(fixUrl ?: return null, interceptor = interceptor).document
val document = app.get(fixUrl ?: return null).document
val title = document.selectFirst("h1.entry-title")?.text()?.removeBloat() ?: return null
val poster = document.selectFirst("div.thumb > img")?.attr("src")
val tags = document.select("div.genre-info > a").map { it.text() }
@ -165,7 +145,6 @@ class Samehadaku : MainAPI() {
this.recommendations = recommendations
addMalId(tracker?.malId)
addAniListId(tracker?.aniId?.toIntOrNull())
posterHeaders = cloudflareKiller.getCookieHeaders(mainUrl).toMap()
}
}
@ -177,7 +156,7 @@ class Samehadaku : MainAPI() {
callback: (ExtractorLink) -> Unit
): Boolean {
val document = app.get(data, interceptor = interceptor).document
val document = app.get(data).document
argamap(
{
@ -196,7 +175,6 @@ class Samehadaku : MainAPI() {
),
referer = data,
headers = mapOf("X-Requested-With" to "XMLHttpRequest"),
interceptor = interceptor
).document.select("iframe").attr("src")
loadFixedExtractor(fixedIframe(iframe), it.text(), "$mainUrl/", subtitleCallback, callback)

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 }
}