From 7f966fac1024fd2920a046f13abf7a1aeb92cb5b Mon Sep 17 00:00:00 2001 From: jack Date: Mon, 11 Dec 2023 11:24:12 +0700 Subject: [PATCH] fix #425 ?? --- .../kotlin/com/hexated/AnimeIndoProvider.kt | 33 +--- Gomov/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/DutaMovie.kt | 2 +- Gomov/src/main/kotlin/com/hexated/Ngefilm.kt | 2 +- .../src/main/kotlin/com/hexated/Nodrakorid.kt | 2 +- .../src/main/kotlin/com/hexated/Minioppai.kt | 27 +-- .../main/kotlin/com/hexated/Movierulzhd.kt | 30 +-- .../src/main/kotlin/com/hexated/Samehadaku.kt | 34 +--- SoraStream/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/Extractors.kt | 9 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 120 +++++------- .../src/main/kotlin/com/hexated/SoraStream.kt | 5 +- .../src/main/kotlin/com/hexated/SoraUtils.kt | 185 +++--------------- 13 files changed, 112 insertions(+), 341 deletions(-) diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt index af29b0076..fcf6489c6 100644 --- a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt +++ b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt @@ -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 { val anime = mutableListOf() (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 } diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts index a19bfe054..dd797cddb 100644 --- a/Gomov/build.gradle.kts +++ b/Gomov/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.konan.properties.Properties // use an integer for version numbers -version = 28 +version = 29 android { defaultConfig { diff --git a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt index deb693ed9..bdd0eb192 100644 --- a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt +++ b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt @@ -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", diff --git a/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt b/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt index 4e2f44cab..5cce06545 100644 --- a/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt +++ b/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt @@ -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( diff --git a/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt b/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt index db3a7845d..0597c5c19 100644 --- a/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt +++ b/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt @@ -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( diff --git a/Minioppai/src/main/kotlin/com/hexated/Minioppai.kt b/Minioppai/src/main/kotlin/com/hexated/Minioppai.kt index 7eedfd012..b7a2a9065 100644 --- a/Minioppai/src/main/kotlin/com/hexated/Minioppai.kt +++ b/Minioppai/src/main/kotlin/com/hexated/Minioppai.kt @@ -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()?.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 -> diff --git a/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt b/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt index 9f6097644..30919b4e9 100644 --- a/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt +++ b/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt @@ -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 { - 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().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( diff --git a/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt b/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt index eb5f1dd8a..51404e623 100644 --- a/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt +++ b/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt @@ -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() 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 { - 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) diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index b02a10d69..94b314cea 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.konan.properties.Properties // use an integer for version numbers -version = 202 +version = 203 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/Extractors.kt b/SoraStream/src/main/kotlin/com/hexated/Extractors.kt index 8187406f4..f2e2739d5 100644 --- a/SoraStream/src/main/kotlin/com/hexated/Extractors.kt +++ b/SoraStream/src/main/kotlin/com/hexated/Extractors.kt @@ -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, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index c66515231..86a8bf09a 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -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 diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 23198212f..ab1908bf9 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -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 ) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index 6aba13373..728bd5270 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -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? = null var filmxyCookies: Map? = 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 { + 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 { - 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? { val req = app.get(url) @@ -780,6 +643,16 @@ suspend fun getTvMoviesServer(url: String, season: Int?, episode: Int?): Pair= it.decimalValue } }