From 38416c118c29ab7a069c248debb193cd53fe6898 Mon Sep 17 00:00:00 2001 From: Olivia Date: Tue, 30 Jan 2024 21:47:49 +0700 Subject: [PATCH] fix --- .../src/main/kotlin/com/hexated/Extractors.kt | 39 +++- .../main/kotlin/com/hexated/SoraExtractor.kt | 203 ++++++------------ .../src/main/kotlin/com/hexated/SoraStream.kt | 32 +-- .../main/kotlin/com/hexated/SoraStreamLite.kt | 10 + .../kotlin/com/hexated/SoraStreamPlugin.kt | 3 + 5 files changed, 125 insertions(+), 162 deletions(-) diff --git a/SoraStream/src/main/kotlin/com/hexated/Extractors.kt b/SoraStream/src/main/kotlin/com/hexated/Extractors.kt index 8026449ce..e6c623f43 100644 --- a/SoraStream/src/main/kotlin/com/hexated/Extractors.kt +++ b/SoraStream/src/main/kotlin/com/hexated/Extractors.kt @@ -337,7 +337,7 @@ open class Netembed : ExtractorApi() { val script = getAndUnpack(response.text) val m3u8 = Regex("((https:|http:)//.*\\.m3u8)").find(script)?.groupValues?.getOrNull(1) ?: return - M3u8Helper.generateM3u8(this.name, m3u8, "$mainUrl/", ).forEach(callback) + M3u8Helper.generateM3u8(this.name, m3u8, "$mainUrl/").forEach(callback) } } @@ -345,6 +345,7 @@ open class Ridoo : ExtractorApi() { override val name = "Ridoo" override var mainUrl = "https://ridoo.net" override val requiresReferer = true + open val defaulQuality = Qualities.P1080.value override suspend fun getUrl( url: String, @@ -359,13 +360,14 @@ open class Ridoo : ExtractorApi() { response.document.selectFirst("script:containsData(sources:)")?.data() } val m3u8 = Regex("file:\\s*\"(.*?m3u8.*?)\"").find(script ?: return)?.groupValues?.getOrNull(1) + val quality = "qualityLabels.*\"(\\d{3,4})[pP]\"".toRegex().find(script)?.groupValues?.get(1) callback.invoke( ExtractorLink( this.name, this.name, m3u8 ?: return, mainUrl, - Qualities.P1080.value, + quality?.toIntOrNull() ?: defaulQuality, INFER_TYPE ) ) @@ -373,6 +375,24 @@ open class Ridoo : ExtractorApi() { } +open class Gdmirrorbot : ExtractorApi() { + override val name = "Gdmirrorbot" + override val mainUrl = "https://gdmirrorbot.nl" + override val requiresReferer = true + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + app.get(url, referer = referer).document.select("ul#videoLinks li").apmap { + loadExtractor(it.attr("data-link"), "$mainUrl/", subtitleCallback, callback) + } + } + +} + open class Streamvid : ExtractorApi() { override val name = "Streamvid" override val mainUrl = "https://streamvid.net" @@ -431,6 +451,18 @@ open class Embedrise : ExtractorApi() { } +class FilemoonNl : Ridoo() { + override val name = "FilemoonNl" + override var mainUrl = "https://filemoon.nl" + override val defaulQuality = Qualities.Unknown.value +} + +class Alions : Ridoo() { + override val name = "Alions" + override var mainUrl = "https://alions.pro" + override val defaulQuality = Qualities.Unknown.value +} + class Streamwish : Filesim() { override val name = "Streamwish" override var mainUrl = "https://streamwish.to" @@ -484,9 +516,10 @@ class Embedwish : Filesim() { override val name = "Embedwish" override var mainUrl = "https://embedwish.com" } -class Flaswish : Filesim() { +class Flaswish : Ridoo() { override val name = "Flaswish" override var mainUrl = "https://flaswish.com" + override val defaulQuality = Qualities.Unknown.value } class Comedyshow : Jeniusplay() { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index b48cc5e1b..eea131eea 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -202,6 +202,29 @@ object SoraExtractor : SoraStream() { } } + suspend fun invokeMoviefiction( + title: String? = null, + season: Int? = null, + episode: Int? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val fixTitle = title?.createSlug() + val url = if (season == null) { + "$moviefictionAPI/movies/$fixTitle" + } else { + "$moviefictionAPI/episode/$fixTitle-${season}x${episode}" + } + val req = app.get(url) + val directUrl = getBaseUrl(req.url) + req.document.select("ul.bx-lst.aa-tbs li a").apmap { + if(!it.select("span.option").text().startsWith("Gdmirrorbot")) return@apmap + val iframe = app.get(base64Decode(it.attr("data-src"))).document.selectFirst("iframe") + ?.attr("src") + loadExtractor(iframe ?: return@apmap, "$directUrl/", subtitleCallback, callback) + } + } + suspend fun invokeAoneroom( title: String? = null, year: Int? = null, @@ -1544,102 +1567,6 @@ object SoraExtractor : SoraStream() { } } - suspend fun invokeMoviezAdd( - apiUrl: String? = null, - api: String? = null, - title: String? = null, - year: Int? = null, - season: Int? = null, - episode: Int? = null, - callback: (ExtractorLink) -> Unit - ) { - invokeBloginguru(apiUrl, api, title, year, season, episode, callback) - } - - suspend fun invokeBollyMaza( - apiUrl: String? = null, - api: String? = null, - title: String? = null, - year: Int? = null, - season: Int? = null, - episode: Int? = null, - callback: (ExtractorLink) -> Unit - ) { - invokeBloginguru(apiUrl, api, title, year, season, episode, callback) - } - - private suspend fun invokeBloginguru( - apiUrl: String? = null, - api: String? = null, - title: String? = null, - year: Int? = null, - season: Int? = null, - episode: Int? = null, - callback: (ExtractorLink) -> Unit - ) { - val fixTitle = title?.createSlug()?.replace("-", " ") - val doc = app.get("$apiUrl/?s=$fixTitle").document - - val matchMedia = doc.select("article.mh-loop-item").map { - it.select("a").attr("href") to it.select("a").text() - }.find { - if (season == null) { - it.second.contains(Regex("(?i)($fixTitle)|($title)")) && it.first.contains("$year") - } else { - it.second.contains(Regex("(?i)($fixTitle)|($title)")) && it.second.contains(Regex("(?i)(Season\\s?$season)|(S0?$season)")) - } - } - - val mediaLink = app.get( - matchMedia?.first - ?: return - ).document.selectFirst("a#jake1")?.attr("href") - val detailDoc = app.get(mediaLink ?: return).document - val media = detailDoc.selectFirst("div.entry-content pre span")?.text()?.split("|") - ?.map { it.trim() } - - val iframe = (if (season == null) { - media?.mapIndexed { index, name -> - detailDoc.select("div.entry-content > h2")[index].selectFirst("a") - ?.attr("href") to name - } - } else { - media?.mapIndexed { index, name -> - val linkMedia = - detailDoc.select("div.entry-content > h2")[index].selectFirst("a")?.attr("href") - app.get( - linkMedia - ?: return@mapIndexed null - ).document.selectFirst("div.entry-content strong:matches((?i)S0?${season}E0?${episode}) a") - ?.attr("href") to name - } - })?.filter { it?.first?.startsWith("http") == true } - - iframe?.apmap { - val iframeDoc = app.get(it?.first ?: return@apmap).document - val formUrl = iframeDoc.select("form").attr("action") - val formData = - iframeDoc.select("form button").associate { v -> v.attr("name") to v.attr("value") } - - val videoUrl = app.post( - formUrl, - data = formData, - referer = it.first - ).document.selectFirst("div.d-flex.justify-content-center.flex-wrap a")?.attr("href") - val quality = - Regex("(\\d{3,4})p").find(it.second)?.groupValues?.getOrNull(1)?.toIntOrNull() - val qualityName = it.second.replace("${quality}p", "").trim() - - callback.invoke( - ExtractorLink( - "$api", "$api $qualityName", videoUrl - ?: return@apmap, "", quality ?: Qualities.Unknown.value - ) - ) - } - - } - suspend fun invokeRStream( id: Int? = null, season: Int? = null, @@ -1749,6 +1676,7 @@ object SoraExtractor : SoraStream() { "Player F" -> { invokeSmashyFfix(it.second, it.first, url, subtitleCallback, callback) } + "Player SU" -> { invokeSmashySu(it.second, it.first, url, callback) } @@ -1765,14 +1693,14 @@ object SoraExtractor : SoraStream() { episode: Int? = null, callback: (ExtractorLink) -> Unit ) { - val id = (if(season == null) { + val id = (if (season == null) { "tmdb|movie|$tmdbId" } else { "tmdb|series|$tmdbId" }).let { base64Encode(it.toByteArray()) } val loaderUrl = "$moflixAPI/api/v1/titles/$id?loader=titlePage" - val url = if(season == null) { + val url = if (season == null) { loaderUrl } else { val mediaId = app.get(loaderUrl, referer = "$moflixAPI/").parsedSafe()?.title?.id @@ -1780,28 +1708,32 @@ object SoraExtractor : SoraStream() { } val res = app.get(url, referer = "$moflixAPI/").parsedSafe() - (res?.episode ?: res?.title)?.videos?.filter { it.category.equals("full", true) }?.apmap { iframe -> - val response = app.get(iframe.src ?: return@apmap, referer = "$moflixAPI/") - val host = getBaseUrl(iframe.src) - val doc = response.document.selectFirst("script:containsData(sources:)")?.data() - val script = if (doc.isNullOrEmpty()) { - getAndUnpack(response.text) - } else { - doc - } - val m3u8 = Regex("file:\\s*\"(.*?m3u8.*?)\"").find(script ?: return@apmap)?.groupValues?.getOrNull(1) - if(m3u8?.haveDub("$host/") == false) return@apmap - callback.invoke( - ExtractorLink( - "Moflix", - "Moflix [${iframe.name}]", - m3u8 ?: return@apmap, - "$host/", - iframe.quality?.filter { it.isDigit() }?.toIntOrNull() ?: Qualities.Unknown.value, - INFER_TYPE + (res?.episode ?: res?.title)?.videos?.filter { it.category.equals("full", true) } + ?.apmap { iframe -> + val response = app.get(iframe.src ?: return@apmap, referer = "$moflixAPI/") + val host = getBaseUrl(iframe.src) + val doc = response.document.selectFirst("script:containsData(sources:)")?.data() + val script = if (doc.isNullOrEmpty()) { + getAndUnpack(response.text) + } else { + doc + } + val m3u8 = Regex("file:\\s*\"(.*?m3u8.*?)\"").find( + script ?: return@apmap + )?.groupValues?.getOrNull(1) + if (m3u8?.haveDub("$host/") == false) return@apmap + callback.invoke( + ExtractorLink( + "Moflix", + "Moflix [${iframe.name}]", + m3u8 ?: return@apmap, + "$host/", + iframe.quality?.filter { it.isDigit() }?.toIntOrNull() + ?: Qualities.Unknown.value, + INFER_TYPE + ) ) - ) - } + } } @@ -2270,14 +2202,15 @@ object SoraExtractor : SoraStream() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit, ) { - val media = app.get("$cinemaTvAPI/v1/${if (season == null) "movies" else "shows"}?filters[q]=$title") - .parsedSafe()?.items?.find { - it.imdb_id?.removePrefix("tt") - .equals(imdbId?.removePrefix("tt")) || (it.title.equals( - title, - true - ) && it.year == year) - } ?: return + val media = + app.get("$cinemaTvAPI/v1/${if (season == null) "movies" else "shows"}?filters[q]=$title") + .parsedSafe()?.items?.find { + it.imdb_id?.removePrefix("tt") + .equals(imdbId?.removePrefix("tt")) || (it.title.equals( + title, + true + ) && it.year == year) + } ?: return val mediaId = if (season == null) { media.id_movie @@ -2286,7 +2219,9 @@ object SoraExtractor : SoraStream() { .parsedSafe()?.episodes?.find { it.episode == episode && it.season == season }?.id } ?: return - val sources = app.get("$cinemaTvAPI/v1/${if (season == null) "movies" else "episodes"}/view?expand=streams,subtitles&id=$mediaId").parsedSafe() + val sources = + app.get("$cinemaTvAPI/v1/${if (season == null) "movies" else "episodes"}/view?expand=streams,subtitles&id=$mediaId") + .parsedSafe() sources?.streams?.mapKeys { source -> callback.invoke( @@ -2340,11 +2275,13 @@ object SoraExtractor : SoraStream() { callback: (ExtractorLink) -> Unit, referer: String = "https://bflix.gs/" ) { - suspend fun String.isSuccess() : Boolean { + suspend fun String.isSuccess(): Boolean { return app.get(this, referer = referer).isSuccessful } + val slug = getEpisodeSlug(season, episode) - var url = if (season == null) "$nowTvAPI/$tmdbId.mp4" else "$nowTvAPI/tv/$tmdbId/s${season}e${slug.second}.mp4" + var url = + if (season == null) "$nowTvAPI/$tmdbId.mp4" else "$nowTvAPI/tv/$tmdbId/s${season}e${slug.second}.mp4" if (!url.isSuccess()) { url = if (season == null) { val temp = "$nowTvAPI/$imdbId.mp4" @@ -2373,7 +2310,8 @@ object SoraExtractor : SoraStream() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit, ) { - val mediaSlug = app.get("$ridomoviesAPI/core/api/search?q=$imdbId").parsedSafe()?.data?.items?.find { + val mediaSlug = app.get("$ridomoviesAPI/core/api/search?q=$imdbId") + .parsedSafe()?.data?.items?.find { it.contentable?.tmdbId == tmdbId || it.contentable?.imdbId == imdbId }?.slug ?: return @@ -2382,7 +2320,8 @@ object SoraExtractor : SoraStream() { app.get(episodeUrl).text.substringAfterLast("""postid\":\"""").substringBefore("""\""") } ?: mediaSlug - val url = "$ridomoviesAPI/core/api/${if (season == null) "movies" else "episodes"}/$id/videos" + val url = + "$ridomoviesAPI/core/api/${if (season == null) "movies" else "episodes"}/$id/videos" app.get(url).parsedSafe()?.data?.apmap { link -> val iframe = Jsoup.parse(link.url ?: return@apmap).select("iframe").attr("data-src") if (iframe.startsWith("https://closeload.top")) { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 8d3033c46..8a26c7ada 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -5,7 +5,6 @@ import com.hexated.SoraExtractor.invoke2embed import com.hexated.SoraExtractor.invokeAllMovieland import com.hexated.SoraExtractor.invokeAnimes import com.hexated.SoraExtractor.invokeAoneroom -import com.hexated.SoraExtractor.invokeBollyMaza import com.hexated.SoraExtractor.invokeFilmxy import com.hexated.SoraExtractor.invokeKimcartoon import com.hexated.SoraExtractor.invokeVidSrc @@ -24,7 +23,6 @@ import com.hexated.SoraExtractor.invokeGoku import com.hexated.SoraExtractor.invokeKisskh import com.hexated.SoraExtractor.invokeLing import com.hexated.SoraExtractor.invokeM4uhd -import com.hexated.SoraExtractor.invokeMoviezAdd import com.hexated.SoraExtractor.invokeNinetv import com.hexated.SoraExtractor.invokeNowTv import com.hexated.SoraExtractor.invokeRStream @@ -43,6 +41,7 @@ import com.hexated.SoraExtractor.invokeVidsrcto import com.hexated.SoraExtractor.invokeCinemaTv import com.hexated.SoraExtractor.invokeMoflix import com.hexated.SoraExtractor.invokeGhostx +import com.hexated.SoraExtractor.invokeMoviefiction import com.hexated.SoraExtractor.invokeWatchCartoon import com.hexated.SoraExtractor.invokeWatchsomuch import com.hexated.SoraExtractor.invokeZshow @@ -83,7 +82,6 @@ open class SoraStream : TmdbProvider() { /** ALL SOURCES */ const val twoEmbedAPI = "https://www.2embed.cc" const val vidSrcAPI = "https://vidsrc.me" - const val dbgoAPI = "https://dbgo.fun" const val dreamfilmAPI = "https://dreamfilmsw.net" const val noverseAPI = "https://www.nollyverse.com" const val filmxyAPI = "https://www.filmxy.vip" @@ -118,6 +116,7 @@ open class SoraStream : TmdbProvider() { const val mMoviesAPI = "https://multimovies.uno" const val watchCartoonAPI = "https://www1.watchcartoononline.bz" const val moflixAPI = "https://moflix-stream.xyz" + const val moviefictionAPI = "https://moviefiction.com" const val fdMoviesAPI = "https://freedrivemovie.com" const val uhdmoviesAPI = "https://uhdmovies.zip" @@ -126,8 +125,6 @@ open class SoraStream : TmdbProvider() { const val vegaMoviesAPI = "https://vegamovies.dad" const val dotmoviesAPI = "https://dotmovies.rsvp" const val tvMoviesAPI = "https://www.tvseriesnmovies.com" - const val moviezAddAPI = "https://ww3.moviezaddiction.click" - const val bollyMazaAPI = "https://ww3.bollymaza.click" const val dahmerMoviesAPI = "https://odd-bird-1319.zwuhygoaqe.workers.dev" fun getType(t: String?): TvType { @@ -507,28 +504,6 @@ open class SoraStream : TmdbProvider() { { if (!res.isAnime) invokeTvMovies(res.title, res.season, res.episode, callback) }, - { - if (!res.isAnime) invokeMoviezAdd( - moviezAddAPI, - "MoviezAdd", - res.title, - res.year, - res.season, - res.episode, - callback - ) - }, - { - if (!res.isAnime && res.isBollywood) invokeBollyMaza( - bollyMazaAPI, - "BollyMaza", - res.title, - res.year, - res.season, - res.episode, - callback - ) - }, { if (!res.isAnime) invokeRStream(res.id, res.season, res.episode, callback) }, @@ -713,6 +688,9 @@ open class SoraStream : TmdbProvider() { { if (!res.isAnime) invokeMoflix(res.id, res.season, res.episode, callback) }, + { + if (!res.isAnime) invokeMoviefiction(res.title, res.season, res.episode, subtitleCallback, callback) + }, ) return true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index 9c09c0472..9da5d53ba 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -29,6 +29,7 @@ import com.hexated.SoraExtractor.invokeVidsrcto import com.hexated.SoraExtractor.invokeCinemaTv import com.hexated.SoraExtractor.invokeMoflix import com.hexated.SoraExtractor.invokeGhostx +import com.hexated.SoraExtractor.invokeMoviefiction import com.hexated.SoraExtractor.invokeWatchCartoon import com.hexated.SoraExtractor.invokeWatchsomuch import com.hexated.SoraExtractor.invokeZshow @@ -319,6 +320,15 @@ class SoraStreamLite : SoraStream() { callback ) }, + { + if (!res.isAnime) invokeMoviefiction( + res.title, + res.season, + res.episode, + subtitleCallback, + callback + ) + }, ) return true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt index 32957fd23..f0f54b5e0 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt @@ -33,5 +33,8 @@ class SoraStreamPlugin: Plugin() { registerExtractorAPI(Ridoo()) registerExtractorAPI(Streamvid()) registerExtractorAPI(Embedrise()) + registerExtractorAPI(Gdmirrorbot()) + registerExtractorAPI(FilemoonNl()) + registerExtractorAPI(Alions()) } } \ No newline at end of file