From 6fbdcf4edcb6f3baf99da80f80f181d0aa5fe44c Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 01:41:51 +0700 Subject: [PATCH 01/22] update Kuramanime domain --- KuramanimeProvider/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/KuramanimeProvider.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/KuramanimeProvider/build.gradle.kts b/KuramanimeProvider/build.gradle.kts index 31e82f6a..e9c83545 100644 --- a/KuramanimeProvider/build.gradle.kts +++ b/KuramanimeProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 12 +version = 13 cloudstream { diff --git a/KuramanimeProvider/src/main/kotlin/com/hexated/KuramanimeProvider.kt b/KuramanimeProvider/src/main/kotlin/com/hexated/KuramanimeProvider.kt index 5d24fcad..989740bb 100644 --- a/KuramanimeProvider/src/main/kotlin/com/hexated/KuramanimeProvider.kt +++ b/KuramanimeProvider/src/main/kotlin/com/hexated/KuramanimeProvider.kt @@ -9,7 +9,7 @@ import org.jsoup.Jsoup import org.jsoup.nodes.Element class KuramanimeProvider : MainAPI() { - override var mainUrl = "https://kuramanime.net" + override var mainUrl = "https://kuramanime.xyz" override var name = "Kuramanime" override val hasQuickSearch = false override val hasMainPage = true From 785eda47c27a7b1971665bb9759ac5137c0b4493 Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 11:56:56 +0700 Subject: [PATCH 02/22] Yomovies: added new source --- YomoviesProvider/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/Extractors.kt | 37 +++++++++++++++++++ .../main/kotlin/com/hexated/Watchomovies.kt | 23 ++++++++++++ .../kotlin/com/hexated/YomoviesProvider.kt | 37 ++++++++----------- .../com/hexated/YomoviesProviderPlugin.kt | 2 + 5 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt create mode 100644 YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt diff --git a/YomoviesProvider/build.gradle.kts b/YomoviesProvider/build.gradle.kts index 8b53037f..42b439cd 100644 --- a/YomoviesProvider/build.gradle.kts +++ b/YomoviesProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 15 +version = 16 cloudstream { diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt b/YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt new file mode 100644 index 00000000..08597bf1 --- /dev/null +++ b/YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt @@ -0,0 +1,37 @@ +package com.hexated + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.extractors.SpeedoStream +import com.lagradost.cloudstream3.utils.AppUtils +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.M3u8Helper +import com.lagradost.cloudstream3.utils.getAndUnpack + +class Streamoupload : SpeedoStream() { + override val mainUrl = "https://streamoupload.xyz" + override val name = "Streamoupload" + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val script = getAndUnpack(app.get(url, referer = referer).text) + val data = script.substringAfter("sources:[") + .substringBefore("],").replace("file", "\"file\"").trim() + AppUtils.tryParseJson(data)?.let { + M3u8Helper.generateM3u8( + name, + it.file, + "$mainUrl/", + ).forEach(callback) + } + } + + private data class File( + @JsonProperty("file") val file: String, + ) +} \ No newline at end of file diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt b/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt new file mode 100644 index 00000000..9ed5ad2d --- /dev/null +++ b/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt @@ -0,0 +1,23 @@ +package com.hexated + +import com.lagradost.cloudstream3.TvType +import com.lagradost.cloudstream3.mainPageOf + +class Watchomovies : YomoviesProvider() { + override var mainUrl = "https://watchomovies.mom" + override var name = "Watchomovies" + override val hasMainPage = true + override var lang = "hi" + override val supportedTypes = setOf( + TvType.NSFW, + ) + + override val mainPage = mainPageOf( + "most-favorites" to "Most Viewed", + "genre/xxx-scenes" to "XXX Scenes", + "genre/18" to "18+ Movies", + "genre/erotic-movies" to "Erotic Movies Movies", + "genre/parody" to "Parody Movies", + "genre/tv-shows" to "TV Shows Movies", + ) +} \ No newline at end of file diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProvider.kt b/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProvider.kt index ac5e991f..1b2bd2a0 100644 --- a/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProvider.kt +++ b/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProvider.kt @@ -9,37 +9,32 @@ import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.nodes.Element import java.net.URI -class YomoviesProvider : MainAPI() { +open class YomoviesProvider : MainAPI() { override var mainUrl = "https://yomovies.baby" - private var directUrl = mainUrl + private var directUrl = "" override var name = "Yomovies" override val hasMainPage = true override var lang = "hi" - override val hasDownloadSupport = true override val supportedTypes = setOf( TvType.Movie, TvType.TvSeries, ) override val mainPage = mainPageOf( - "$mainUrl/most-favorites/page/" to "Most Viewed", - "$mainUrl/genre/web-series/page/" to "Web Series Movies", - "$mainUrl/genre/dual-audio/page/" to "Dual Audio Movies", - "$mainUrl/genre/bollywood/page/" to "Bollywood Movies", - "$mainUrl/genre/tv-shows/page/" to "TV Shows Movies", - "$mainUrl/genre/hollywood/page/" to "Hollywood Movies", - "$mainUrl/series/page/" to "All TV Series", + "most-favorites" to "Most Viewed", + "genre/web-series" to "Web Series Movies", + "genre/dual-audio" to "Dual Audio Movies", + "genre/bollywood" to "Bollywood Movies", + "genre/tv-shows" to "TV Shows Movies", + "genre/hollywood" to "Hollywood Movies", + "series" to "All TV Series", ) override suspend fun getMainPage( page: Int, request: MainPageRequest ): HomePageResponse { - val document = if (page == 1) { - app.get(request.data.removeSuffix("page/")).document - } else { - app.get(request.data + page).document - } + val document = app.get("$mainUrl/${request.data}/page/$page").document val home = document.select("div.ml-item").mapNotNull { it.toSearchResult() } @@ -129,12 +124,6 @@ class YomoviesProvider : MainAPI() { } } - private fun getBaseUrl(url: String): String { - return URI(url).let { - "${it.scheme}://${it.host}" - } - } - override suspend fun loadLinks( data: String, isCasting: Boolean, @@ -175,4 +164,10 @@ class YomoviesProvider : MainAPI() { return fixTitle(URI(this).host.substringBeforeLast(".").substringAfterLast(".")) } + private fun getBaseUrl(url: String): String { + return URI(url).let { + "${it.scheme}://${it.host}" + } + } + } diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt b/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt index 72cbcd16..60bb8004 100644 --- a/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt +++ b/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt @@ -10,5 +10,7 @@ class YomoviesProviderPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(YomoviesProvider()) + registerMainAPI(Watchomovies()) + registerExtractorAPI(Streamoupload()) } } \ No newline at end of file From a55dc31798b066f2d02ddb2d8f17196f55b7c15f Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 14:08:39 +0700 Subject: [PATCH 03/22] added Gomov --- Gomov/build.gradle.kts | 27 +++ Gomov/src/main/AndroidManifest.xml | 2 + Gomov/src/main/kotlin/com/hexated/Gomov.kt | 176 ++++++++++++++++++ .../main/kotlin/com/hexated/GomovPlugin.kt | 17 ++ 4 files changed, 222 insertions(+) create mode 100644 Gomov/build.gradle.kts create mode 100644 Gomov/src/main/AndroidManifest.xml create mode 100644 Gomov/src/main/kotlin/com/hexated/Gomov.kt create mode 100644 Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts new file mode 100644 index 00000000..5db843c0 --- /dev/null +++ b/Gomov/build.gradle.kts @@ -0,0 +1,27 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + language = "id" + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + authors = listOf("Hexated") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + tvTypes = listOf( + "AsianDrama", + "TvSeries", + "Movie", + ) + + iconUrl = "https://www.google.com/s2/favicons?domain=gomov.bio&sz=%size%" +} \ No newline at end of file diff --git a/Gomov/src/main/AndroidManifest.xml b/Gomov/src/main/AndroidManifest.xml new file mode 100644 index 00000000..c98063f8 --- /dev/null +++ b/Gomov/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/Gomov.kt b/Gomov/src/main/kotlin/com/hexated/Gomov.kt new file mode 100644 index 00000000..3d92217d --- /dev/null +++ b/Gomov/src/main/kotlin/com/hexated/Gomov.kt @@ -0,0 +1,176 @@ +package com.hexated + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addActors +import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer +import com.lagradost.cloudstream3.extractors.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.httpsify +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.nodes.Element + +class Gomov : MainAPI() { + override var mainUrl = "https://gomov.bio" + override var name = "Gomov" + override val hasMainPage = true + override var lang = "id" + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + TvType.AsianDrama + ) + + override val mainPage = mainPageOf( + "page/%d/?s&search=advanced&post_type=movie" to "Movies", + "category/western-series/page/%d/" to "Western Series", + "tv/page/%d/" to "Tv Shows", + "category/korean-series/page/%d/" to "Korean Series", + "category/chinese-series/page/%d/" to "Chinese Series", + "category/india-series/page/%d/" to "India Series", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val data = request.data.format(page) + val document = app.get("$mainUrl/$data").document + val home = document.select("article.item").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse(request.name, home) + } + + private fun Element.toSearchResult(): SearchResponse? { + val title = this.selectFirst("h2.entry-title > a")?.text()?.trim() ?: return null + val href = fixUrl(this.selectFirst("a")!!.attr("href")) + val posterUrl = fixUrlNull(this.selectFirst("a > img")?.attr("src")) + val quality = this.select("div.gmr-qual").text().trim() + return if (quality.isEmpty()) { + val episode = this.select("div.gmr-numbeps > span").text().toIntOrNull() + newAnimeSearchResponse(title, href, TvType.TvSeries) { + this.posterUrl = posterUrl + addSub(episode) + } + } else { + newMovieSearchResponse(title, href, TvType.Movie) { + this.posterUrl = posterUrl + addQuality(quality) + } + } + } + + private fun Element.toBottomSearchResult(): SearchResponse? { + val title = this.selectFirst("a > span.idmuvi-rp-title")?.text()?.trim() ?: return null + val href = this.selectFirst("a")!!.attr("href") + val posterUrl = fixUrl(this.selectFirst("a > img")?.attr("data-src").toString()) + return newMovieSearchResponse(title, href, TvType.Movie) { + this.posterUrl = posterUrl + } + } + + override suspend fun search(query: String): List { + return app.get("$mainUrl/?s=$query&post_type[]=post&post_type[]=tv").document.select("article.item") + .mapNotNull { + it.toSearchResult() + } + } + + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + + val title = + document.selectFirst("h1.entry-title")?.text()?.substringBefore("Season")?.trim() + .toString() + val poster = + fixUrl(document.selectFirst("figure.pull-left > img")?.attr("src").toString()) + val tags = document.select("span.gmr-movie-genre:contains(Genre:) > a").map { it.text() } + + val year = + document.select("span.gmr-movie-genre:contains(Year:) > a").text().trim().toIntOrNull() + val tvType = if (url.contains("/tv/")) TvType.TvSeries else TvType.Movie + val description = document.selectFirst("div[itemprop=description] > p")?.text()?.trim() + val trailer = document.selectFirst("ul.gmr-player-nav li a.gmr-trailer-popup")?.attr("href") + val rating = + document.selectFirst("div.gmr-meta-rating > span[itemprop=ratingValue]")?.text() + ?.toRatingInt() + val actors = document.select("div.gmr-moviedata").last()?.select("span[itemprop=actors]") + ?.map { it.select("a").text() } + + val recommendations = document.select("div.idmuvi-rp ul li").mapNotNull { + it.toBottomSearchResult() + } + + return if (tvType == TvType.TvSeries) { + val episodes = document.select("div.vid-episodes div.episode").map { eps -> + val href = fixUrl(eps.select("a").attr("href")) + val episode = eps.attr("data-epi").toIntOrNull() + val season = eps.attr("data-sea").toIntOrNull() + Episode( + href, + season = season, + episode = episode, + ) + } + newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { + this.posterUrl = poster + this.year = year + this.plot = description + this.tags = tags + this.rating = rating + addActors(actors) + this.recommendations = recommendations + addTrailer(trailer) + } + } else { + newMovieLoadResponse(title, url, TvType.Movie, url) { + this.posterUrl = poster + this.year = year + this.plot = description + this.tags = tags + this.rating = rating + addActors(actors) + this.recommendations = recommendations + addTrailer(trailer) + } + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + val document = app.get(data).document + val id = document.selectFirst("div#muvipro_player_content_id")!!.attr("data-id") + + document.select("div.tab-content-ajax").apmap { + val server = app.post( + "$mainUrl/wp-admin/admin-ajax.php", + data = mapOf("action" to "muvipro_player_content", "tab" to it.attr("id"), "post_id" to id) + ).document.select("iframe").attr("src") + + loadExtractor(httpsify(server), "$mainUrl/", subtitleCallback, callback) + } + + return true + + } + +} + +class Filelions : Filesim() { + override val name = "Filelions" + override var mainUrl = "https://filelions.to" +} + +class Likessb : StreamSB() { + override var name = "Likessb" + override var mainUrl = "https://likessb.com" +} + +class DbGdriveplayer : Gdriveplayer() { + override var mainUrl = "https://database.gdriveplayer.us" +} \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt new file mode 100644 index 00000000..05c8715b --- /dev/null +++ b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt @@ -0,0 +1,17 @@ + +package com.hexated + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class GomovPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(Gomov()) + registerExtractorAPI(Filelions()) + registerExtractorAPI(Likessb()) + registerExtractorAPI(DbGdriveplayer()) + } +} \ No newline at end of file From e1cbf5be2ef49580055b307c0a76445ff1f972a7 Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 15:44:27 +0700 Subject: [PATCH 04/22] Gomov: added Dutamovie --- Gomov/build.gradle.kts | 4 +- .../src/main/kotlin/com/hexated/DutaMovie.kt | 44 +++++++++++++++++++ .../src/main/kotlin/com/hexated/Extractors.kt | 24 ++++++++++ Gomov/src/main/kotlin/com/hexated/Gomov.kt | 29 ++++-------- .../main/kotlin/com/hexated/GomovPlugin.kt | 2 + YomoviesProvider/build.gradle.kts | 2 +- 6 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 Gomov/src/main/kotlin/com/hexated/DutaMovie.kt create mode 100644 Gomov/src/main/kotlin/com/hexated/Extractors.kt diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts index 5db843c0..58ecbc21 100644 --- a/Gomov/build.gradle.kts +++ b/Gomov/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { language = "id" // All of these properties are optional, you can safely remove them - // description = "Lorem Ipsum" + description = "Include: DutaMovie" authors = listOf("Hexated") /** diff --git a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt new file mode 100644 index 00000000..01a903bb --- /dev/null +++ b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt @@ -0,0 +1,44 @@ +package com.hexated + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.httpsify +import com.lagradost.cloudstream3.utils.loadExtractor + +class DutaMovie : Gomov() { + override var mainUrl = "https://dutamovie21.live" + override var name = "DutaMovie" + override val hasMainPage = true + override var lang = "id" + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + TvType.AsianDrama + ) + + override val mainPage = mainPageOf( + "category/box-office/page/%d/" to "Box Office", + "category/serial-tv/page/%d/" to "Serial TV", + "category/animation/page/%d/" to "Animasi", + "country/korea/page/%d/" to "Serial TV Korea", + "country/indonesia/page/%d/" to "Serial TV Indonesia", + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + app.get(data).document.select("ul.muvipro-player-tabs li a").apmap { + val iframe = app.get(fixUrl(it.attr("href"))).document.selectFirst("div.gmr-embed-responsive iframe") + ?.attr("src") + loadExtractor(httpsify(iframe ?: return@apmap ), "$mainUrl/", subtitleCallback, callback) + } + + return true + } + + +} \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/Extractors.kt b/Gomov/src/main/kotlin/com/hexated/Extractors.kt new file mode 100644 index 00000000..25bd9f11 --- /dev/null +++ b/Gomov/src/main/kotlin/com/hexated/Extractors.kt @@ -0,0 +1,24 @@ +package com.hexated + +import com.lagradost.cloudstream3.extractors.Filesim +import com.lagradost.cloudstream3.extractors.Gdriveplayer +import com.lagradost.cloudstream3.extractors.StreamSB + +class Dutamovie21 : StreamSB() { + override var name = "Dutamovie21" + override var mainUrl = "https://dutamovie21.xyz" +} + +class Filelions : Filesim() { + override val name = "Filelions" + override var mainUrl = "https://filelions.to" +} + +class Likessb : StreamSB() { + override var name = "Likessb" + override var mainUrl = "https://likessb.com" +} + +class DbGdriveplayer : Gdriveplayer() { + override var mainUrl = "https://database.gdriveplayer.us" +} \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/Gomov.kt b/Gomov/src/main/kotlin/com/hexated/Gomov.kt index 3d92217d..2c2b1d36 100644 --- a/Gomov/src/main/kotlin/com/hexated/Gomov.kt +++ b/Gomov/src/main/kotlin/com/hexated/Gomov.kt @@ -3,13 +3,12 @@ package com.hexated import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.LoadResponse.Companion.addActors import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer -import com.lagradost.cloudstream3.extractors.* import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.httpsify import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.nodes.Element -class Gomov : MainAPI() { +open class Gomov : MainAPI() { override var mainUrl = "https://gomov.bio" override var name = "Gomov" override val hasMainPage = true @@ -102,16 +101,18 @@ class Gomov : MainAPI() { } return if (tvType == TvType.TvSeries) { - val episodes = document.select("div.vid-episodes div.episode").map { eps -> - val href = fixUrl(eps.select("a").attr("href")) - val episode = eps.attr("data-epi").toIntOrNull() - val season = eps.attr("data-sea").toIntOrNull() + val episodes = document.select("div.vid-episodes a, div.gmr-listseries a").map { eps -> + val href = fixUrl(eps.attr("href")) + val name = eps.text() + val episode = name.split(" ").lastOrNull()?.filter { it.isDigit() }?.toIntOrNull() + val season = name.split(" ").firstOrNull()?.filter { it.isDigit() }?.toIntOrNull() Episode( href, + name, season = season, episode = episode, ) - } + }.filter { it.episode != null } newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { this.posterUrl = poster this.year = year @@ -159,18 +160,4 @@ class Gomov : MainAPI() { } -} - -class Filelions : Filesim() { - override val name = "Filelions" - override var mainUrl = "https://filelions.to" -} - -class Likessb : StreamSB() { - override var name = "Likessb" - override var mainUrl = "https://likessb.com" -} - -class DbGdriveplayer : Gdriveplayer() { - override var mainUrl = "https://database.gdriveplayer.us" } \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt index 05c8715b..99c3213d 100644 --- a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt +++ b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt @@ -10,8 +10,10 @@ class GomovPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(Gomov()) + registerMainAPI(DutaMovie()) registerExtractorAPI(Filelions()) registerExtractorAPI(Likessb()) registerExtractorAPI(DbGdriveplayer()) + registerExtractorAPI(Dutamovie21()) } } \ No newline at end of file diff --git a/YomoviesProvider/build.gradle.kts b/YomoviesProvider/build.gradle.kts index 42b439cd..f00bbb7e 100644 --- a/YomoviesProvider/build.gradle.kts +++ b/YomoviesProvider/build.gradle.kts @@ -6,7 +6,7 @@ cloudstream { language = "hi" // All of these properties are optional, you can safely remove them - // description = "Lorem Ipsum" + description = "Include: Watchomovies" authors = listOf("Hexated") /** From 0561fcf85751efaeb32db4d51025ac09d68929b9 Mon Sep 17 00:00:00 2001 From: tuan041 <30403510+tuan041@users.noreply.github.com> Date: Thu, 20 Jul 2023 15:50:17 +0700 Subject: [PATCH 05/22] Add Phim1080 Provider (#197) * bump * fix * new * new * new * new * change version --- Phim1080/build.gradle.kts | 28 ++ Phim1080/src/main/AndroidManifest.xml | 2 + .../src/main/com/hexated/Phim1080Provider.kt | 247 ++++++++++++++++++ .../com/hexated/Phim1080ProviderPlugin.kt | 14 + 4 files changed, 291 insertions(+) create mode 100644 Phim1080/build.gradle.kts create mode 100644 Phim1080/src/main/AndroidManifest.xml create mode 100644 Phim1080/src/main/com/hexated/Phim1080Provider.kt create mode 100644 Phim1080/src/main/com/hexated/Phim1080ProviderPlugin.kt diff --git a/Phim1080/build.gradle.kts b/Phim1080/build.gradle.kts new file mode 100644 index 00000000..bd0faf7c --- /dev/null +++ b/Phim1080/build.gradle.kts @@ -0,0 +1,28 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + language = "vi" + // All of these properties are optional, you can safely remove them + + description = "Xem Phim Online Chất Lượng Cao" + authors = listOf("TuaSan") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + tvTypes = listOf( + "AsianDrama", + "Anime", + "TvSeries", + "Movie", + ) + + iconUrl = "https://www.google.com/s2/favicons?domain=xem1080.com" +} diff --git a/Phim1080/src/main/AndroidManifest.xml b/Phim1080/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a3f95b4f --- /dev/null +++ b/Phim1080/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/Phim1080/src/main/com/hexated/Phim1080Provider.kt b/Phim1080/src/main/com/hexated/Phim1080Provider.kt new file mode 100644 index 00000000..d4d35368 --- /dev/null +++ b/Phim1080/src/main/com/hexated/Phim1080Provider.kt @@ -0,0 +1,247 @@ +package com.hexated + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer +import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import org.jsoup.nodes.Element + +class Phim1080Provider : MainAPI() { + override var mainUrl = "https://xem1080.com" + override var name = "Phim1080" + override val hasMainPage = true + override var lang = "vi" + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + TvType.Anime, + TvType.AsianDrama + ) + + private fun encodeString(e: String, t: Int): String { + var a = "" + for (i in 0 until e.length) { + val r = e[i].code + val o = r xor t + a += o.toChar() + } + return a + } + + override val mainPage = mainPageOf( + "$mainUrl/phim-de-cu?page=" to "Phim Đề Cử", + "$mainUrl/the-loai/hoat-hinh?page=" to "Phim Hoạt Hình", + "$mainUrl/phim-chieu-rap?page=" to "Phim Chiếu Rạp", + "$mainUrl/phim-bo?page=" to "Phim Bộ", + "$mainUrl/phim-le?page=" to "Phim Lẻ", + "$mainUrl/bang-xep-hang?page=" to "Bảng Xếp Hạng", + "$mainUrl/bo-suu-tap/disney-plus?page=" to "Disney+", + "$mainUrl/bo-suu-tap/netflix-original?page=" to "Netflix", + "$mainUrl/hom-nay-xem-gi?page=" to "Hôm Nay Xem Gì", + "$mainUrl/phim-sap-chieu?page=" to "Phim Sắp Chiếu", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val document = app.get(request.data + page).document + val home = document.select("div.tray-item").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse( + list = HomePageList( + name = request.name, + list = home, + ), + hasNext = true + ) + } + + private fun Element.toSearchResult(): SearchResponse { + val title = this.selectFirst("div.tray-item-title")?.text()?.trim().toString() + val href = fixUrl(this.selectFirst("a")!!.attr("href")) + val posterUrl = this.selectFirst("img")!!.attr("data-src") + val temp = this.select("div.tray-film-likes").text() + return if (temp.contains("/")) { + val episode = Regex("((\\d+)\\s)").find(temp)?.groupValues?.map { num -> + num.replace(Regex("\\s"), "") + }?.distinct()?.firstOrNull()?.toIntOrNull() + newAnimeSearchResponse(title, href, TvType.TvSeries) { + this.posterUrl = posterUrl + addSub(episode) + } + } else { + val quality = this.select("span.tray-item-quality").text().replace("FHD", "HD").trim() + newMovieSearchResponse(title, href, TvType.Movie) { + this.posterUrl = posterUrl + addQuality(quality) + } + } + } + + override suspend fun search(query: String): List { + val link = "$mainUrl/tim-kiem/$query" + val document = app.get(link).document + + return document.select("div.tray-item").map { + it.toSearchResult() + } + } + + override suspend fun load( url: String ): LoadResponse { + val document = app.get( + url = url, + referer = "$mainUrl/", + headers = mapOf( + "Sec-Ch-Ua-Mobile" to "?1", + "Sec-Ch-Ua-Platform" to "\"Android\"", + "User-Agent" to "Mozilla/5.0 (Linux; Android 10; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Mobile Safari/537.36 Edg/114.0.0.0", + ) + ).document + val fId = document.select("div.container").attr("data-id") + val filmInfo = app.get( + "$mainUrl/api/v2/films/$fId", + referer = url, + headers = mapOf( + "Content-Type" to "application/json", + "X-Requested-With" to "XMLHttpRequest" + ) + ).parsedSafe() + val title = filmInfo?.name?.trim().toString() + val poster = filmInfo?.thumbnail + val background = filmInfo?.poster + val slug = filmInfo?.slug + val link = "$mainUrl/$slug" + val tags = document.select("div.film-content div.film-info-genre:nth-child(7) a").map { it.text() } + val year = filmInfo?.year + val tvType = if (document.select("div.episode-group-tab").isNotEmpty()) TvType.TvSeries else TvType.Movie + val description = document.select("div.film-info-description").text().trim() + val comingSoon = document.select("button.direction-trailer").isNotEmpty() + val trailerCode = filmInfo?.trailer?.original?.id + val trailer = "https://www.youtube.com/embed/$trailerCode" + val recommendations = document.select("section.tray.index.related div.tray-content.carousel div.tray-item").map { + it.toSearchResult() + } + + return if (tvType == TvType.TvSeries) { + val epsInfo = app.get( + "$mainUrl/api/v2/films/$fId/episodes?sort=name", + referer = link, + headers = mapOf( + "Content-Type" to "application/json", + "X-Requested-With" to "XMLHttpRequest", + ) + ).parsedSafe()?.eps?.map { ep -> + Episode( + data = fixUrl(ep.link.toString()), + name = ep.detailname, + episode = ep.episodeNumber, + ) + } ?: listOf() + newTvSeriesLoadResponse(title, url, TvType.TvSeries, epsInfo) { + this.posterUrl = poster + this.backgroundPosterUrl = background + this.year = year + this.plot = description + this.tags = tags + this.comingSoon = comingSoon + addTrailer(trailer) + this.recommendations = recommendations + } + } else { + newMovieLoadResponse(title, url, TvType.Movie, link) { + this.posterUrl = poster + this.backgroundPosterUrl = background + this.year = year + this.plot = description + this.tags = tags + this.comingSoon = comingSoon + addTrailer(trailer) + this.recommendations = recommendations + } + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + val document = app.get(data).document + val fId = document.select("div.container").attr("data-id") + val epId = document.select("div.container").attr("data-episode-id") + val doc = app.get( + "$mainUrl/api/v2/films/$fId/episodes/$epId", + referer = data, + headers = mapOf( + "Content-Type" to "application/json", + "cookie" to "xem1080=%3D", + "X-Requested-With" to "XMLHttpRequest" + ) + ) + val source = doc.text.substringAfter(":{\"hls\":\"").substringBefore("\"},") + val link = encodeString(source, 69) + callback.invoke( + ExtractorLink( + "HS", + "HS", + link, + referer = data, + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + val subId = doc.parsedSafe()?.subtitle?.vi + val isSubIdEmpty = subId.isNullOrBlank() + if (!isSubIdEmpty) { + subtitleCallback.invoke( + SubtitleFile( + "Vietnamese", + "$mainUrl/subtitle/$subId.vtt" + ) + ) + } + return true + } + + data class filmInfo( + @JsonProperty("name") val name: String? = null, + @JsonProperty("poster") val poster: String? = null, + @JsonProperty("thumbnail") val thumbnail: String? = null, + @JsonProperty("slug") val slug: String? = null, + @JsonProperty("year") val year: Int? = null, + @JsonProperty("trailer") val trailer: TrailerInfo? = null, + ) + + data class TrailerInfo( + @JsonProperty("original") val original: TrailerKey? = null, + ) + + data class TrailerKey( + @JsonProperty("id") val id: String? = null, + ) + + data class MediaDetailEpisodes( + @JsonProperty("data") val eps: ArrayList? = arrayListOf(), + ) + + data class Episodes( + @JsonProperty("link") val link: String? = null, + @JsonProperty("detail_name") val detailname: String? = null, + @JsonProperty("name") val episodeNumber: Int? = null, + ) + + data class Media( + @JsonProperty("subtitle") val subtitle: SubInfo? = null, + ) + + data class SubInfo( + @JsonProperty("vi") val vi: String? = null, + ) + +} diff --git a/Phim1080/src/main/com/hexated/Phim1080ProviderPlugin.kt b/Phim1080/src/main/com/hexated/Phim1080ProviderPlugin.kt new file mode 100644 index 00000000..a521b6ac --- /dev/null +++ b/Phim1080/src/main/com/hexated/Phim1080ProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.hexated + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class Phim1080ProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(Phim1080Provider()) + } +} From 46c67dbd35d444198492d9f03639fdb5855ab48a Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 16:11:14 +0700 Subject: [PATCH 06/22] small fix --- Phim1080/src/main/{ => kotlin}/com/hexated/Phim1080Provider.kt | 0 .../src/main/{ => kotlin}/com/hexated/Phim1080ProviderPlugin.kt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Phim1080/src/main/{ => kotlin}/com/hexated/Phim1080Provider.kt (100%) rename Phim1080/src/main/{ => kotlin}/com/hexated/Phim1080ProviderPlugin.kt (100%) diff --git a/Phim1080/src/main/com/hexated/Phim1080Provider.kt b/Phim1080/src/main/kotlin/com/hexated/Phim1080Provider.kt similarity index 100% rename from Phim1080/src/main/com/hexated/Phim1080Provider.kt rename to Phim1080/src/main/kotlin/com/hexated/Phim1080Provider.kt diff --git a/Phim1080/src/main/com/hexated/Phim1080ProviderPlugin.kt b/Phim1080/src/main/kotlin/com/hexated/Phim1080ProviderPlugin.kt similarity index 100% rename from Phim1080/src/main/com/hexated/Phim1080ProviderPlugin.kt rename to Phim1080/src/main/kotlin/com/hexated/Phim1080ProviderPlugin.kt From 864b266f9ef981260b9cdd85cd9ea348a7397486 Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 19:35:26 +0700 Subject: [PATCH 07/22] fixed Rebahin and moved Ngefilm --- Gomov/build.gradle.kts | 4 +- .../src/main/kotlin/com/hexated/DutaMovie.kt | 7 - Gomov/src/main/kotlin/com/hexated/Gomov.kt | 21 ++- .../main/kotlin/com/hexated/GomovPlugin.kt | 1 + Gomov/src/main/kotlin/com/hexated/Ngefilm.kt | 40 +++++ Ngefilm/build.gradle.kts | 27 --- Ngefilm/src/main/AndroidManifest.xml | 2 - .../src/main/kotlin/com/hexated/Ngefilm.kt | 164 ------------------ .../main/kotlin/com/hexated/NgefilmPlugin.kt | 14 -- .../kotlin/com/hexated/Phim1080Provider.kt | 8 +- RebahinProvider/build.gradle.kts | 4 +- .../src/main/kotlin/com/hexated/Cgvindo.kt | 9 + .../kotlin/com/hexated/RebahinProvider.kt | 3 +- .../com/hexated/RebahinProviderPlugin.kt | 6 +- 14 files changed, 76 insertions(+), 234 deletions(-) create mode 100644 Gomov/src/main/kotlin/com/hexated/Ngefilm.kt delete mode 100644 Ngefilm/build.gradle.kts delete mode 100644 Ngefilm/src/main/AndroidManifest.xml delete mode 100644 Ngefilm/src/main/kotlin/com/hexated/Ngefilm.kt delete mode 100644 Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt create mode 100644 RebahinProvider/src/main/kotlin/com/hexated/Cgvindo.kt diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts index 58ecbc21..7f2b8216 100644 --- a/Gomov/build.gradle.kts +++ b/Gomov/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 2 +version = 3 cloudstream { language = "id" // All of these properties are optional, you can safely remove them - description = "Include: DutaMovie" + description = "Include: DutaMovie, Ngefilm" authors = listOf("Hexated") /** diff --git a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt index 01a903bb..7912713c 100644 --- a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt +++ b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt @@ -8,13 +8,6 @@ import com.lagradost.cloudstream3.utils.loadExtractor class DutaMovie : Gomov() { override var mainUrl = "https://dutamovie21.live" override var name = "DutaMovie" - override val hasMainPage = true - override var lang = "id" - override val supportedTypes = setOf( - TvType.Movie, - TvType.TvSeries, - TvType.AsianDrama - ) override val mainPage = mainPageOf( "category/box-office/page/%d/" to "Box Office", diff --git a/Gomov/src/main/kotlin/com/hexated/Gomov.kt b/Gomov/src/main/kotlin/com/hexated/Gomov.kt index 2c2b1d36..36128fb2 100644 --- a/Gomov/src/main/kotlin/com/hexated/Gomov.kt +++ b/Gomov/src/main/kotlin/com/hexated/Gomov.kt @@ -43,8 +43,8 @@ open class Gomov : MainAPI() { private fun Element.toSearchResult(): SearchResponse? { val title = this.selectFirst("h2.entry-title > a")?.text()?.trim() ?: return null val href = fixUrl(this.selectFirst("a")!!.attr("href")) - val posterUrl = fixUrlNull(this.selectFirst("a > img")?.attr("src")) - val quality = this.select("div.gmr-qual").text().trim() + val posterUrl = fixUrlNull(this.selectFirst("a > img")?.attr("src"))?.fixImageQuality() + val quality = this.select("div.gmr-qual, div.gmr-quality-item > a").text().trim().replace("-", "") return if (quality.isEmpty()) { val episode = this.select("div.gmr-numbeps > span").text().toIntOrNull() newAnimeSearchResponse(title, href, TvType.TvSeries) { @@ -59,10 +59,10 @@ open class Gomov : MainAPI() { } } - private fun Element.toBottomSearchResult(): SearchResponse? { + private fun Element.toRecommendResult(): SearchResponse? { val title = this.selectFirst("a > span.idmuvi-rp-title")?.text()?.trim() ?: return null val href = this.selectFirst("a")!!.attr("href") - val posterUrl = fixUrl(this.selectFirst("a > img")?.attr("data-src").toString()) + val posterUrl = fixUrlNull(this.selectFirst("a > img")?.attr("src").fixImageQuality()) return newMovieSearchResponse(title, href, TvType.Movie) { this.posterUrl = posterUrl } @@ -82,7 +82,7 @@ open class Gomov : MainAPI() { document.selectFirst("h1.entry-title")?.text()?.substringBefore("Season")?.trim() .toString() val poster = - fixUrl(document.selectFirst("figure.pull-left > img")?.attr("src").toString()) + fixUrlNull(document.selectFirst("figure.pull-left > img")?.attr("src"))?.fixImageQuality() val tags = document.select("span.gmr-movie-genre:contains(Genre:) > a").map { it.text() } val year = @@ -97,7 +97,7 @@ open class Gomov : MainAPI() { ?.map { it.select("a").text() } val recommendations = document.select("div.idmuvi-rp ul li").mapNotNull { - it.toBottomSearchResult() + it.toRecommendResult() } return if (tvType == TvType.TvSeries) { @@ -109,7 +109,7 @@ open class Gomov : MainAPI() { Episode( href, name, - season = season, + season = if(name.contains(" ")) season else null, episode = episode, ) }.filter { it.episode != null } @@ -160,4 +160,11 @@ open class Gomov : MainAPI() { } + private fun String?.fixImageQuality(): String? { + if(this == null) return null + val regex = Regex("(-\\d*x\\d*)").find(this)?.groupValues + if(regex?.isEmpty() == true) return this + return this.replace(regex?.get(0) ?: return null, "") + } + } \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt index 99c3213d..b3043cb7 100644 --- a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt +++ b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt @@ -11,6 +11,7 @@ class GomovPlugin: Plugin() { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(Gomov()) registerMainAPI(DutaMovie()) + registerMainAPI(Ngefilm()) registerExtractorAPI(Filelions()) registerExtractorAPI(Likessb()) registerExtractorAPI(DbGdriveplayer()) diff --git a/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt b/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt new file mode 100644 index 00000000..7c4be51f --- /dev/null +++ b/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt @@ -0,0 +1,40 @@ +package com.hexated + +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.apmap +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.fixUrl +import com.lagradost.cloudstream3.mainPageOf +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor + +class Ngefilm : Gomov() { + override var mainUrl = "https://ngefilm21.lol" + override var name = "Ngefilm" + + override val mainPage = mainPageOf( + "/page/%d/?s&search=advanced&post_type=movie&index&orderby&genre&movieyear&country&quality=" to "Movies Terbaru", + "/page/%d/?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=&quality=" to "Series Terbaru", + "/page/%d/?s=&search=advanced&post_type=tv&index=&orderby=&genre=drakor&movieyear=&country=&quality=" to "Series Korea", + "/page/%d/?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=indonesia&quality=" to "Series Indonesia", + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + val document = app.get(data).document + document.select("ul.muvipro-player-tabs li a").apmap { server -> + val iframe = app.get(fixUrl(server.attr("href"))).document.selectFirst("div.gmr-embed-responsive iframe") + ?.attr("src")?.let { fixUrl(it) } ?: return@apmap + loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback) + } + + return true + + } + +} \ No newline at end of file diff --git a/Ngefilm/build.gradle.kts b/Ngefilm/build.gradle.kts deleted file mode 100644 index 0903f827..00000000 --- a/Ngefilm/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -// use an integer for version numbers -version = 4 - - -cloudstream { - language = "id" - // All of these properties are optional, you can safely remove them - - // description = "Lorem Ipsum" - authors = listOf("Hexated") - - /** - * Status int as the following: - * 0: Down - * 1: Ok - * 2: Slow - * 3: Beta only - * */ - status = 1 // will be 3 if unspecified - tvTypes = listOf( - "AsianDrama", - "TvSeries", - "Movie", - ) - - iconUrl = "https://www.google.com/s2/favicons?domain=ngefilm21.club&sz=%size%" -} \ No newline at end of file diff --git a/Ngefilm/src/main/AndroidManifest.xml b/Ngefilm/src/main/AndroidManifest.xml deleted file mode 100644 index c98063f8..00000000 --- a/Ngefilm/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Ngefilm/src/main/kotlin/com/hexated/Ngefilm.kt b/Ngefilm/src/main/kotlin/com/hexated/Ngefilm.kt deleted file mode 100644 index 84a14d7d..00000000 --- a/Ngefilm/src/main/kotlin/com/hexated/Ngefilm.kt +++ /dev/null @@ -1,164 +0,0 @@ -package com.hexated - -import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.LoadResponse.Companion.addActors -import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer -import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.loadExtractor -import org.jsoup.nodes.Element - -class Ngefilm : MainAPI() { - override var mainUrl = "https://ngefilm21.cfd" - override var name = "Ngefilm" - override val hasMainPage = true - override var lang = "id" - override val hasDownloadSupport = true - override val supportedTypes = setOf( - TvType.Movie, - TvType.TvSeries, - TvType.AsianDrama - ) - - override val mainPage = mainPageOf( - "?s&search=advanced&post_type=movie&index&orderby&genre&movieyear&country&quality=" to "Movies Terbaru", - "?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=&quality=" to "Series Terbaru", - "?s=&search=advanced&post_type=tv&index=&orderby=&genre=drakor&movieyear=&country=&quality=" to "Series Korea", - "?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=indonesia&quality=" to "Series Indonesia", - ) - - override suspend fun getMainPage( - page: Int, - request: MainPageRequest - ): HomePageResponse { - val document = app.get("$mainUrl/page/$page/${request.data}").document - val home = document.select("main#main article").mapNotNull { - it.toSearchResult() - } - return newHomePageResponse(request.name, home) - } - - override suspend fun search(query: String): List { - val link = "$mainUrl/?s=$query&post_type[]=post&post_type[]=tv" - val document = app.get(link).document - return document.select("main#main article").mapNotNull { - it.toSearchResult() - } - } - - override suspend fun load(url: String): LoadResponse { - val document = app.get(url).document - - val title = - document.selectFirst("h1.entry-title")?.text()?.substringBefore("Season")?.trim() ?: "" - val poster = fixUrlNull( - document.selectFirst("figure.pull-left > img")?.attr("src")?.fixImageQuality() - ) - val tags = document.select("span.gmr-movie-genre:contains(Genre:) > a").map { it.text() } - - val year = - document.select("span.gmr-movie-genre:contains(Year:) > a").text().trim().toIntOrNull() - val tvType = if (url.contains("/tv/")) TvType.TvSeries else TvType.Movie - val description = document.selectFirst("div[itemprop=description] > p")?.text()?.trim() - val trailer = document.selectFirst("ul.gmr-player-nav li a.gmr-trailer-popup")?.attr("href") - val rating = - document.selectFirst("div.gmr-meta-rating > span[itemprop=ratingValue]")?.text() - ?.toRatingInt() - val actors = document.select("div.gmr-moviedata").last()?.select("span[itemprop=actors]") - ?.map { it.select("a").text() } - - val recommendations = document.select("div.idmuvi-rp ul li").mapNotNull { - it.toRecommendResult() - } - - return if (tvType == TvType.TvSeries) { - val episodes = document.select("div.gmr-listseries > a") - .filter { element -> !element.text().contains("Pilih Episode", true) } - .map { eps -> - val href = fixUrl(eps.attr("href")) - val episode = eps.text().substringAfter("Eps").toIntOrNull() - val season = - eps.text().split(" ").first().substringAfter("S").toIntOrNull() ?: 1 - Episode( - href, - season = season, - episode = episode, - ) - } - newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { - this.posterUrl = poster - this.year = year - this.plot = description - this.tags = tags - this.rating = rating - addActors(actors) - this.recommendations = recommendations - addTrailer(trailer) - } - } else { - newMovieLoadResponse(title, url, TvType.Movie, url) { - this.posterUrl = poster - this.year = year - this.plot = description - this.tags = tags - this.rating = rating - addActors(actors) - this.recommendations = recommendations - addTrailer(trailer) - } - } - } - - override suspend fun loadLinks( - data: String, - isCasting: Boolean, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit - ): Boolean { - - val document = app.get(data).document - - document.select("ul.muvipro-player-tabs li a").apmap { server -> - val iframe = app.get(fixUrl(server.attr("href"))).document.selectFirst("div.gmr-embed-responsive iframe") - ?.attr("src")?.let { fixUrl(it) } ?: return@apmap - loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback) - } - - return true - - } - - private fun Element.toSearchResult(): SearchResponse? { - val title = this.selectFirst("h2.entry-title > a")?.text()?.trim() ?: return null - val href = fixUrl(this.selectFirst("a")?.attr("href") ?: return null) - val posterUrl = fixUrlNull(this.selectFirst("a > img")?.attr("src").fixImageQuality()) - val quality = this.select("div.gmr-quality-item > a").text().trim() - return if (quality.isEmpty()) { - val episode = - this.select("div.gmr-numbeps > span").text().filter { it.isDigit() }.toIntOrNull() - newAnimeSearchResponse(title, href, TvType.TvSeries) { - this.posterUrl = posterUrl - addSub(episode) - } - } else { - newMovieSearchResponse(title, href, TvType.Movie) { - this.posterUrl = posterUrl - addQuality(quality.replace("-", "")) - } - } - } - - private fun Element.toRecommendResult(): SearchResponse? { - val title = this.selectFirst("a > span.idmuvi-rp-title")?.text()?.trim() ?: return null - val href = this.selectFirst("a")!!.attr("href") - val posterUrl = fixUrlNull(this.selectFirst("a > img")?.attr("src").fixImageQuality()) - return newMovieSearchResponse(title, href, TvType.Movie) { - this.posterUrl = posterUrl - } - } - - private fun String?.fixImageQuality(): String? { - val quality = Regex("(-\\d*x\\d*)").find(this ?: return null)?.groupValues?.get(0) - return this.replace(quality ?: return null, "") - } - -} \ No newline at end of file diff --git a/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt b/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt deleted file mode 100644 index 8fc845f8..00000000 --- a/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt +++ /dev/null @@ -1,14 +0,0 @@ - -package com.hexated - -import com.lagradost.cloudstream3.plugins.CloudstreamPlugin -import com.lagradost.cloudstream3.plugins.Plugin -import android.content.Context - -@CloudstreamPlugin -class NgefilmPlugin: Plugin() { - override fun load(context: Context) { - // All providers should be added in this manner. Please don't edit the providers list directly. - registerMainAPI(Ngefilm()) - } -} \ No newline at end of file diff --git a/Phim1080/src/main/kotlin/com/hexated/Phim1080Provider.kt b/Phim1080/src/main/kotlin/com/hexated/Phim1080Provider.kt index d4d35368..edadf591 100644 --- a/Phim1080/src/main/kotlin/com/hexated/Phim1080Provider.kt +++ b/Phim1080/src/main/kotlin/com/hexated/Phim1080Provider.kt @@ -22,8 +22,8 @@ class Phim1080Provider : MainAPI() { private fun encodeString(e: String, t: Int): String { var a = "" - for (i in 0 until e.length) { - val r = e[i].code + for (element in e) { + val r = element.code val o = r xor t a += o.toChar() } @@ -109,7 +109,7 @@ class Phim1080Provider : MainAPI() { "Content-Type" to "application/json", "X-Requested-With" to "XMLHttpRequest" ) - ).parsedSafe() + ).parsedSafe() val title = filmInfo?.name?.trim().toString() val poster = filmInfo?.thumbnail val background = filmInfo?.poster @@ -209,7 +209,7 @@ class Phim1080Provider : MainAPI() { return true } - data class filmInfo( + data class FilmInfo( @JsonProperty("name") val name: String? = null, @JsonProperty("poster") val poster: String? = null, @JsonProperty("thumbnail") val thumbnail: String? = null, diff --git a/RebahinProvider/build.gradle.kts b/RebahinProvider/build.gradle.kts index 32b9dd7e..0c5b2fdf 100644 --- a/RebahinProvider/build.gradle.kts +++ b/RebahinProvider/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 6 +version = 7 cloudstream { language = "id" // All of these properties are optional, you can safely remove them - // description = "Lorem Ipsum" + description = "Include: Cgvindo, Kitanonton" authors = listOf("Hexated") /** diff --git a/RebahinProvider/src/main/kotlin/com/hexated/Cgvindo.kt b/RebahinProvider/src/main/kotlin/com/hexated/Cgvindo.kt new file mode 100644 index 00000000..328f0a06 --- /dev/null +++ b/RebahinProvider/src/main/kotlin/com/hexated/Cgvindo.kt @@ -0,0 +1,9 @@ +package com.hexated + +import com.lagradost.cloudstream3.TvType + +class Cgvindo : RebahinProvider() { + override var mainUrl = "http://cgvindo.click" + override var name = "Cgvindo" + +} \ No newline at end of file diff --git a/RebahinProvider/src/main/kotlin/com/hexated/RebahinProvider.kt b/RebahinProvider/src/main/kotlin/com/hexated/RebahinProvider.kt index e8e5ad1e..fcb63f6e 100644 --- a/RebahinProvider/src/main/kotlin/com/hexated/RebahinProvider.kt +++ b/RebahinProvider/src/main/kotlin/com/hexated/RebahinProvider.kt @@ -13,11 +13,10 @@ import org.jsoup.nodes.Element import java.net.URI open class RebahinProvider : MainAPI() { - override var mainUrl = "http://104.237.198.198" + override var mainUrl = "http://179.43.163.50" override var name = "Rebahin" override val hasMainPage = true override var lang = "id" - override val hasDownloadSupport = true open var mainServer = "http://172.96.161.72" override val supportedTypes = setOf( TvType.Movie, diff --git a/RebahinProvider/src/main/kotlin/com/hexated/RebahinProviderPlugin.kt b/RebahinProvider/src/main/kotlin/com/hexated/RebahinProviderPlugin.kt index ab58bb2d..e051cc41 100644 --- a/RebahinProvider/src/main/kotlin/com/hexated/RebahinProviderPlugin.kt +++ b/RebahinProvider/src/main/kotlin/com/hexated/RebahinProviderPlugin.kt @@ -1,4 +1,3 @@ - package com.hexated import com.lagradost.cloudstream3.plugins.CloudstreamPlugin @@ -6,10 +5,11 @@ import com.lagradost.cloudstream3.plugins.Plugin import android.content.Context @CloudstreamPlugin -class RebahinProviderPlugin: Plugin() { +class RebahinProviderPlugin : Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(RebahinProvider()) -registerMainAPI(Kitanonton()) + registerMainAPI(Kitanonton()) + registerMainAPI(Cgvindo()) } } \ No newline at end of file From ee302555a5d661effdc8dc559e85e742db5f5649 Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 20:26:43 +0700 Subject: [PATCH 08/22] AnimeIndoProvider: fixed homepage --- AnimeIndoProvider/build.gradle.kts | 2 +- .../kotlin/com/hexated/AnimeIndoProvider.kt | 35 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/AnimeIndoProvider/build.gradle.kts b/AnimeIndoProvider/build.gradle.kts index 1b1a9869..297bbcc1 100644 --- a/AnimeIndoProvider/build.gradle.kts +++ b/AnimeIndoProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 10 +version = 11 cloudstream { diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt index 4c40ad78..b518016b 100644 --- a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt +++ b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt @@ -13,7 +13,6 @@ class AnimeIndoProvider : MainAPI() { override var name = "AnimeIndo" override val hasMainPage = true override var lang = "id" - override val hasDownloadSupport = true override val supportedTypes = setOf( TvType.Anime, @@ -39,18 +38,19 @@ class AnimeIndoProvider : MainAPI() { } override val mainPage = mainPageOf( - "$mainUrl/anime-terbaru/page/" to "Anime Terbaru", - "$mainUrl/ongoing/page/" to "Anime Ongoing", - "$mainUrl/populer/page/" to "Anime Populer", - "$mainUrl/donghua-terbaru/page/" to "Donghua Terbaru", + "episode-terbaru" to "Episode Terbaru", + "ongoing" to "Anime Ongoing", + "populer" to "Anime Populer", + "donghua-terbaru" to "Donghua Terbaru", ) override suspend fun getMainPage( page: Int, request: MainPageRequest ): HomePageResponse { - val document = app.get(request.data + page).document - val home = document.select("div.post-show > article, div.relat > article").mapNotNull { + val url = "$mainUrl/pages/${request.data}/page/$page" + val document = app.get(url).document + val home = document.select("main#main div.animposx").mapNotNull { it.toSearchResult() } return newHomePageResponse(request.name, home) @@ -60,7 +60,7 @@ class AnimeIndoProvider : MainAPI() { return if (uri.contains("/anime/")) { uri } else { - var title = uri.substringAfter("$mainUrl/") + var title = uri.substringAfter("nonton/") title = when { (title.contains("-episode")) && !(title.contains("-movie")) -> Regex("(.+)-episode").find( title @@ -74,15 +74,13 @@ class AnimeIndoProvider : MainAPI() { } } - private fun Element.toSearchResult(): AnimeSearchResponse? { - val title = this.selectFirst("div.title")?.text()?.trim() ?: return null + private fun Element.toSearchResult(): AnimeSearchResponse { + val title = this.selectFirst("div.titlex, h2.entry-title, h4")?.text()?.trim() ?: "" val href = getProperAnimeLink(this.selectFirst("a")!!.attr("href")) - val posterUrl = this.select("img[itemprop=image]").attr("src").toString() - val type = getType(this.select("div.type").text().trim()) - val epNum = - this.selectFirst("span.episode")?.ownText()?.replace(Regex("\\D"), "")?.trim() - ?.toIntOrNull() - return newAnimeSearchResponse(title, href, type) { + val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src")) + val epNum = this.selectFirst("span.episode")?.ownText()?.replace(Regex("\\D"), "")?.trim() + ?.toIntOrNull() + return newAnimeSearchResponse(title, href, TvType.Anime) { this.posterUrl = posterUrl addSub(epNum) } @@ -131,6 +129,10 @@ class AnimeIndoProvider : MainAPI() { Episode(link, header.text(), episode = episode) }.reversed() + val recommendations = document.select("div.relat div.animposx").mapNotNull { + it.toSearchResult() + } + return newAnimeLoadResponse(title, url, getType(type)) { engName = title posterUrl = poster @@ -139,6 +141,7 @@ class AnimeIndoProvider : MainAPI() { showStatus = status plot = description this.tags = tags + this.recommendations = recommendations addTrailer(trailer) } } From 8b9a58a5a0f77e58532817170a9f182147edd20e Mon Sep 17 00:00:00 2001 From: sora Date: Thu, 20 Jul 2023 23:07:46 +0700 Subject: [PATCH 09/22] small fix --- Nekopoi/build.gradle.kts | 2 +- Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Nekopoi/build.gradle.kts b/Nekopoi/build.gradle.kts index 2eb99748..c3c51979 100644 --- a/Nekopoi/build.gradle.kts +++ b/Nekopoi/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt b/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt index 9c0a4cb7..f94d78f8 100644 --- a/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt +++ b/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt @@ -155,8 +155,8 @@ class Nekopoi : MainAPI() { ) to ele.selectFirst("a:contains(ouo)") ?.attr("href") }.filter { it.first != Qualities.P360.value }.map { - val bypassedAds = bypassMirrored(bypassOuo(it.second ?: return@map) ?: return@map) - bypassedAds.apmap ads@{ adsLink -> + val bypassedAds = bypassMirrored(bypassOuo(it.second)) + bypassedAds.amap ads@{ adsLink -> loadExtractor( fixEmbed(adsLink) ?: return@ads, "$mainUrl/", @@ -225,8 +225,8 @@ class Nekopoi : MainAPI() { return res.headers["location"] } - private suspend fun bypassMirrored(url: String): List { - val request = app.get(url) + private suspend fun bypassMirrored(url: String?): List { + val request = app.get(url ?: return emptyList()) val hostUrl = getBaseUrl(request.url) var nextUrl = request.document.selectFirst("div.row div.centered a")?.attr("href") nextUrl = app.get(nextUrl ?: return emptyList()).text.substringAfter("\"GET\", \"") @@ -234,11 +234,11 @@ class Nekopoi : MainAPI() { return app.get(fixUrl(nextUrl, hostUrl)).document.select("table.hoverable tbody tr") .filter { mirror -> !mirrorIsBlackList(mirror.selectFirst("img")?.attr("alt")) - }.apmap { + }.amap { val fileLink = it.selectFirst("a")?.attr("href") app.get( fixUrl( - fileLink.toString(), + fileLink ?: return@amap null, hostUrl ) ).document.selectFirst("div.code_wrap code")?.text() From 65f5283ae60d69536b7f2b2a6dc502bdd4ddd9f3 Mon Sep 17 00:00:00 2001 From: hexated Date: Fri, 21 Jul 2023 00:49:46 +0700 Subject: [PATCH 10/22] TimefourTv: fix DaddyHD Channels --- TimefourTv/build.gradle.kts | 2 +- TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt | 7 +++++-- .../src/main/kotlin/com/hexated/TimefourTvExtractor.kt | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/TimefourTv/build.gradle.kts b/TimefourTv/build.gradle.kts index fa742b08..dbde5cf2 100644 --- a/TimefourTv/build.gradle.kts +++ b/TimefourTv/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 14 +version = 15 cloudstream { diff --git a/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt b/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt index d1a32510..b5b0dbb0 100644 --- a/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt +++ b/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt @@ -19,8 +19,11 @@ open class TimefourTv : MainAPI() { ) companion object { - const val daddyUrl = "https://daddylive.watch" - val daddyHost: String = URI(daddyUrl).host.split(".").first() + const val daddyUrl = "https://d.daddylivehd.sx" + val daddyHost: String = daddyUrl.getHost() + private fun String.getHost(): String { + return URI(this).host.substringBeforeLast(".").substringAfterLast(".") + } } override val mainPage = mainPageOf( diff --git a/TimefourTv/src/main/kotlin/com/hexated/TimefourTvExtractor.kt b/TimefourTv/src/main/kotlin/com/hexated/TimefourTvExtractor.kt index c56fae01..57d484a2 100644 --- a/TimefourTv/src/main/kotlin/com/hexated/TimefourTvExtractor.kt +++ b/TimefourTv/src/main/kotlin/com/hexated/TimefourTvExtractor.kt @@ -72,7 +72,7 @@ object TimefourTvExtractor : TimefourTv() { return getSportLink(url) } - if(url.contains(daddyHost)) { + if(url.contains(daddyHost, true)) { mainServer = getBaseUrl(url) return getFinalLink(app.get(url, referer = daddyUrl)) } From 3b907e3d5a384ae3e7bbb12c47b7818b14e29c1f Mon Sep 17 00:00:00 2001 From: hexated Date: Fri, 21 Jul 2023 16:55:03 +0700 Subject: [PATCH 11/22] sora: fixed Smashy and Fdmovies --- SoraStream/build.gradle.kts | 2 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 11 ++++++- .../src/main/kotlin/com/hexated/SoraUtils.kt | 33 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index c770eba3..f035b3fd 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 = 144 +version = 145 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 933475ca..ad127d88 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -1491,7 +1491,13 @@ object SoraExtractor : SoraStream() { extractGdflix(gdBotLink ?: return@apmap null) } type.contains("oiya") -> { - extractOiya(fdLink ?: return@apmap null, qualities) + val oiyaLink = extractOiya(fdLink ?: return@apmap null, qualities) + if(oiyaLink?.contains("gdtot") == true) { + val gdBotLink = extractGdbot(oiyaLink) + extractGdflix(gdBotLink ?: return@apmap null) + } else { + oiyaLink + } } else -> { return@apmap null @@ -2041,6 +2047,9 @@ object SoraExtractor : SoraStream() { it.first.contains("/rip") -> { invokeSmashyRip(it.second, it.first, subtitleCallback, callback) } + it.first.contains("/im.php") && !isAnime -> { + invokeSmashyIm(it.second, it.first, subtitleCallback, callback) + } else -> return@apmap } } diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index 524470c6..38416433 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -563,6 +563,39 @@ suspend fun invokeSmashyRip( } +suspend fun invokeSmashyIm( + name: String, + url: String, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, +) { + val script = + app.get(url).document.selectFirst("script:containsData(player =)")?.data() ?: return + + val sources = + Regex("['\"]?file['\"]?:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1) ?: return + val subtitles = + Regex("['\"]?subtitle['\"]?:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1) ?: return + + M3u8Helper.generateM3u8( + name, + sources, + "" + ).forEach(callback) + + subtitles.split(",").map { sub -> + val lang = Regex("\\[(.*?)]").find(sub)?.groupValues?.getOrNull(1)?.trim() + val trimmedSubLink = sub.removePrefix("[$lang]").trim().substringAfter("?url=") + subtitleCallback.invoke( + SubtitleFile( + lang.takeIf { !it.isNullOrEmpty() } ?: return@map, + trimmedSubLink + ) + ) + } + +} + suspend fun getDumpIdAndType(title: String?, year: Int?, season: Int?): Pair { val res = tryParseJson( queryApi( From 92bd21310a0e5019ae0fddaa64ac60cff2decadf Mon Sep 17 00:00:00 2001 From: hexated Date: Fri, 21 Jul 2023 20:47:12 +0700 Subject: [PATCH 12/22] fixed DramaidProvider --- DramaidProvider/build.gradle.kts | 2 +- DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt | 2 +- MultiplexProvider/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/MultiplexProvider.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DramaidProvider/build.gradle.kts b/DramaidProvider/build.gradle.kts index 42fd4171..ac1628ab 100644 --- a/DramaidProvider/build.gradle.kts +++ b/DramaidProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 6 +version = 7 cloudstream { diff --git a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt index d1e90376..ad96071f 100644 --- a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt +++ b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt @@ -203,7 +203,7 @@ class DramaidProvider : MainAPI() { it.replace("https://ndrama.xyz", "https://www.fembed.com") }.apmap { when { - it.contains("motonews.club") -> invokeDriveSource( + it.contains("motonews") -> invokeDriveSource( it, this.name, subtitleCallback, diff --git a/MultiplexProvider/build.gradle.kts b/MultiplexProvider/build.gradle.kts index aaeb74f5..51ca5d94 100644 --- a/MultiplexProvider/build.gradle.kts +++ b/MultiplexProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/MultiplexProvider/src/main/kotlin/com/hexated/MultiplexProvider.kt b/MultiplexProvider/src/main/kotlin/com/hexated/MultiplexProvider.kt index 851c267e..7a76be91 100644 --- a/MultiplexProvider/src/main/kotlin/com/hexated/MultiplexProvider.kt +++ b/MultiplexProvider/src/main/kotlin/com/hexated/MultiplexProvider.kt @@ -10,7 +10,7 @@ import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.nodes.Element class MultiplexProvider : MainAPI() { - override var mainUrl = "https://146.19.24.137" + override var mainUrl = "http://5.104.81.46" override var name = "Multiplex" override val hasMainPage = true override var lang = "id" From b8b87dea74ca8f00d85c6a8c2e1f1ff396e428e6 Mon Sep 17 00:00:00 2001 From: sora Date: Fri, 21 Jul 2023 23:17:23 +0700 Subject: [PATCH 13/22] nekopoi: fix video loading --- Nekopoi/build.gradle.kts | 2 +- Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Nekopoi/build.gradle.kts b/Nekopoi/build.gradle.kts index c3c51979..a8c9601a 100644 --- a/Nekopoi/build.gradle.kts +++ b/Nekopoi/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 2 +version = 3 cloudstream { diff --git a/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt b/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt index f94d78f8..27ecc2e8 100644 --- a/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt +++ b/Nekopoi/src/main/kotlin/com/hexated/Nekopoi.kt @@ -30,6 +30,7 @@ class Nekopoi : MainAPI() { "SendCm", "GoogleDrive", ) + const val mirroredHost = "https://www.mirrored.to" fun getStatus(t: String?): ShowStatus { return when (t) { @@ -156,7 +157,7 @@ class Nekopoi : MainAPI() { ?.attr("href") }.filter { it.first != Qualities.P360.value }.map { val bypassedAds = bypassMirrored(bypassOuo(it.second)) - bypassedAds.amap ads@{ adsLink -> + bypassedAds.apmap ads@{ adsLink -> loadExtractor( fixEmbed(adsLink) ?: return@ads, "$mainUrl/", @@ -227,19 +228,18 @@ class Nekopoi : MainAPI() { private suspend fun bypassMirrored(url: String?): List { val request = app.get(url ?: return emptyList()) - val hostUrl = getBaseUrl(request.url) var nextUrl = request.document.selectFirst("div.row div.centered a")?.attr("href") nextUrl = app.get(nextUrl ?: return emptyList()).text.substringAfter("\"GET\", \"") .substringBefore("\"") - return app.get(fixUrl(nextUrl, hostUrl)).document.select("table.hoverable tbody tr") + return app.get(fixUrl(nextUrl, mirroredHost)).document.select("table.hoverable tbody tr") .filter { mirror -> !mirrorIsBlackList(mirror.selectFirst("img")?.attr("alt")) - }.amap { + }.apmap { val fileLink = it.selectFirst("a")?.attr("href") app.get( fixUrl( - fileLink ?: return@amap null, - hostUrl + fileLink ?: return@apmap null, + mirroredHost ) ).document.selectFirst("div.code_wrap code")?.text() } From 89a619929b25ff9321f71c9c62c5f7ab009c57c4 Mon Sep 17 00:00:00 2001 From: sora Date: Sat, 22 Jul 2023 12:45:24 +0700 Subject: [PATCH 14/22] changed daddyhd domain --- TimefourTv/build.gradle.kts | 2 +- TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt | 2 +- YomoviesProvider/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/Watchomovies.kt | 8 ++++++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/TimefourTv/build.gradle.kts b/TimefourTv/build.gradle.kts index dbde5cf2..3fb6e15e 100644 --- a/TimefourTv/build.gradle.kts +++ b/TimefourTv/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 15 +version = 16 cloudstream { diff --git a/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt b/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt index b5b0dbb0..7b68e7a7 100644 --- a/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt +++ b/TimefourTv/src/main/kotlin/com/hexated/TimefourTv.kt @@ -19,7 +19,7 @@ open class TimefourTv : MainAPI() { ) companion object { - const val daddyUrl = "https://d.daddylivehd.sx" + const val daddyUrl = "https://daddylivehd.com" val daddyHost: String = daddyUrl.getHost() private fun String.getHost(): String { return URI(this).host.substringBeforeLast(".").substringAfterLast(".") diff --git a/YomoviesProvider/build.gradle.kts b/YomoviesProvider/build.gradle.kts index f00bbb7e..f5249c1c 100644 --- a/YomoviesProvider/build.gradle.kts +++ b/YomoviesProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 16 +version = 17 cloudstream { diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt b/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt index 9ed5ad2d..cca19de1 100644 --- a/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt +++ b/YomoviesProvider/src/main/kotlin/com/hexated/Watchomovies.kt @@ -1,13 +1,13 @@ package com.hexated +import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.mainPageOf class Watchomovies : YomoviesProvider() { override var mainUrl = "https://watchomovies.mom" override var name = "Watchomovies" - override val hasMainPage = true - override var lang = "hi" + override var lang = "en" override val supportedTypes = setOf( TvType.NSFW, ) @@ -20,4 +20,8 @@ class Watchomovies : YomoviesProvider() { "genre/parody" to "Parody Movies", "genre/tv-shows" to "TV Shows Movies", ) + + override suspend fun load(url: String): LoadResponse? { + return super.load(url).apply { this?.type = TvType.NSFW } + } } \ No newline at end of file From 031aa780c95a6855e96b59440132570b18b81415 Mon Sep 17 00:00:00 2001 From: sora Date: Sat, 22 Jul 2023 14:59:26 +0700 Subject: [PATCH 15/22] added Oppadrama --- DramaidProvider/build.gradle.kts | 4 +- .../kotlin/com/hexated/DramaidProvider.kt | 101 ++++++++---------- .../com/hexated/DramaidProviderPlugin.kt | 1 + .../src/main/kotlin/com/hexated/Oppadrama.kt | 6 ++ Gomov/build.gradle.kts | 2 +- 5 files changed, 55 insertions(+), 59 deletions(-) create mode 100644 DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt diff --git a/DramaidProvider/build.gradle.kts b/DramaidProvider/build.gradle.kts index ac1628ab..a1beeb4d 100644 --- a/DramaidProvider/build.gradle.kts +++ b/DramaidProvider/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 7 +version = 8 cloudstream { language = "id" // All of these properties are optional, you can safely remove them - // description = "Lorem Ipsum" + description = "Include: Oppadrama" authors = listOf("Hexated") /** diff --git a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt index ad96071f..a757305d 100644 --- a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt +++ b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt @@ -10,14 +10,11 @@ import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup import org.jsoup.nodes.Element -class DramaidProvider : MainAPI() { +open class DramaidProvider : MainAPI() { override var mainUrl = "https://dramaid.best" override var name = "DramaId" - override val hasQuickSearch = false override val hasMainPage = true override var lang = "id" - override val hasDownloadSupport = true - override val hasChromecastSupport = false override val supportedTypes = setOf(TvType.AsianDrama) companion object { @@ -28,6 +25,14 @@ class DramaidProvider : MainAPI() { else -> ShowStatus.Completed } } + + fun getType(t: String?): TvType { + return when { + t?.contains("Movie", true) == true -> TvType.Movie + t?.contains("Anime", true) == true -> TvType.Anime + else -> TvType.AsianDrama + } + } } override val mainPage = mainPageOf( @@ -45,18 +50,19 @@ class DramaidProvider : MainAPI() { } private fun getProperDramaLink(uri: String): String { - return if (uri.contains("/series/")) { - uri - } else { + return if (uri.contains("-episode-")) { "$mainUrl/series/" + Regex("$mainUrl/(.+)-ep.+").find(uri)?.groupValues?.get(1) - .toString() + } else { + uri } } private fun Element.toSearchResult(): SearchResponse? { val href = getProperDramaLink(this.selectFirst("a.tip")!!.attr("href")) val title = this.selectFirst("h2[itemprop=headline]")?.text()?.trim() ?: return null - val posterUrl = fixUrlNull(this.selectFirst(".limit > noscript > img")?.attr("src")) + val posterUrl = fixUrlNull( + this.selectFirst("noscript img")?.attr("src") ?: this.selectFirst("img")?.attr("src") + ) return newTvSeriesSearchResponse(title, href, TvType.AsianDrama) { this.posterUrl = posterUrl @@ -64,27 +70,19 @@ class DramaidProvider : MainAPI() { } override suspend fun search(query: String): List { - val link = "$mainUrl/?s=$query" - val document = app.get(link).document - - return document.select("article[itemscope=itemscope]").map { - val title = it.selectFirst("h2[itemprop=headline]")!!.text().trim() - val poster = it.selectFirst(".limit > noscript > img")!!.attr("src") - val href = it.selectFirst("a.tip")!!.attr("href") - - newTvSeriesSearchResponse(title, href, TvType.AsianDrama) { - this.posterUrl = poster - } + val document = app.get("$mainUrl/?s=$query").document + return document.select("article[itemscope=itemscope]").mapNotNull { + it.toSearchResult() } } override suspend fun load(url: String): LoadResponse { val document = app.get(url).document - val title = document.selectFirst("h1.entry-title")!!.text().trim() - val poster = document.select(".thumb > noscript > img").attr("src") + val title = document.selectFirst("h1.entry-title")?.text()?.trim() ?: "" + val poster = fixUrlNull(document.selectFirst("div.thumb noscript img")?.attr("src") ?: document.selectFirst("div.thumb img")?.attr("src")) val tags = document.select(".genxed > a").map { it.text() } - + val type = document.selectFirst(".info-content .spe span:contains(Tipe:)")?.ownText() val year = Regex("\\d, ([0-9]*)").find( document.selectFirst(".info-content > .spe > span > time")!!.text().trim() )?.groupValues?.get(1).toString().toIntOrNull() @@ -94,44 +92,34 @@ class DramaidProvider : MainAPI() { ) val description = document.select(".entry-content > p").text().trim() - val episodes = document.select(".eplister > ul > li").map { - val name = it.selectFirst("a > .epl-title")!!.text().trim() - val link = it.select("a").attr("href") - val epNum = it.selectFirst("a > .epl-num")!!.text().trim().toIntOrNull() - newEpisode(link) { - this.name = name - this.episode = epNum - } + val episodes = document.select(".eplister > ul > li").mapNotNull { + val name = it.selectFirst("a > .epl-title")?.text() + val link = fixUrl(it.selectFirst("a")?.attr("href") ?: return@mapNotNull null) + val epNum = it.selectFirst(".epl-num")?.text()?.toIntOrNull() + Episode( + link, + name, + episode = epNum + ) }.reversed() val recommendations = - document.select(".listupd > article[itemscope=itemscope]").map { rec -> - val epTitle = rec.selectFirst("h2[itemprop=headline]")!!.text().trim() - val epPoster = rec.selectFirst(".limit > noscript > img")!!.attr("src") - val epHref = fixUrl(rec.selectFirst("a.tip")!!.attr("href")) - - newTvSeriesSearchResponse(epTitle, epHref, TvType.AsianDrama) { - this.posterUrl = epPoster - } + document.select(".listupd > article[itemscope=itemscope]").mapNotNull { rec -> + rec.toSearchResult() } - if (episodes.size == 1) { - return newMovieLoadResponse(title, url, TvType.Movie, episodes[0].data) { - posterUrl = poster - this.year = year - plot = description - this.tags = tags - this.recommendations = recommendations - } - } else { - return newTvSeriesLoadResponse(title, url, TvType.AsianDrama, episodes = episodes) { - posterUrl = poster - this.year = year - showStatus = status - plot = description - this.tags = tags - this.recommendations = recommendations - } + return newTvSeriesLoadResponse( + title, + url, + getType(type), + episodes = episodes + ) { + posterUrl = poster + this.year = year + showStatus = status + plot = description + this.tags = tags + this.recommendations = recommendations } } @@ -209,6 +197,7 @@ class DramaidProvider : MainAPI() { subtitleCallback, callback ) + else -> loadExtractor(it, data, subtitleCallback, callback) } } diff --git a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProviderPlugin.kt b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProviderPlugin.kt index 78c28ae2..bcf9ac4f 100644 --- a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProviderPlugin.kt +++ b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProviderPlugin.kt @@ -10,6 +10,7 @@ class DramaidProviderPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(DramaidProvider()) + registerMainAPI(Oppadrama()) registerExtractorAPI(Vanfem()) } } \ No newline at end of file diff --git a/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt b/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt new file mode 100644 index 00000000..44dcb365 --- /dev/null +++ b/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt @@ -0,0 +1,6 @@ +package com.hexated + +class Oppadrama : DramaidProvider() { + override var mainUrl = "http://185.217.95.34" + override var name = "Oppadrama" +} \ No newline at end of file diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts index 7f2b8216..71e8c9c4 100644 --- a/Gomov/build.gradle.kts +++ b/Gomov/build.gradle.kts @@ -6,7 +6,7 @@ cloudstream { language = "id" // All of these properties are optional, you can safely remove them - description = "Include: DutaMovie, Ngefilm" + description = "Include: DutaMovie, Ngefilm" authors = listOf("Hexated") /** From bf9d2d5c31e5ca2346afd508bf9c60498ae0c728 Mon Sep 17 00:00:00 2001 From: hexated Date: Sat, 22 Jul 2023 21:48:46 +0700 Subject: [PATCH 16/22] fix marin in anichi and added Nodrakorid --- Anichi/build.gradle.kts | 2 +- .../kotlin/com/hexated/AnichiExtractors.kt | 21 ++++++++++--------- .../kotlin/com/hexated/DramaidProvider.kt | 7 +++---- .../src/main/kotlin/com/hexated/DutaMovie.kt | 2 +- .../main/kotlin/com/hexated/GomovPlugin.kt | 1 + Gomov/src/main/kotlin/com/hexated/Ngefilm.kt | 20 +----------------- .../src/main/kotlin/com/hexated/Nodrakorid.kt | 16 ++++++++++++++ 7 files changed, 34 insertions(+), 35 deletions(-) create mode 100644 Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt diff --git a/Anichi/build.gradle.kts b/Anichi/build.gradle.kts index 1a2f6d64..dcc2cb7b 100644 --- a/Anichi/build.gradle.kts +++ b/Anichi/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.konan.properties.Properties // use an integer for version numbers -version = 6 +version = 7 android { defaultConfig { diff --git a/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt b/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt index 5fe9ab9f..d5811278 100644 --- a/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt +++ b/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt @@ -6,6 +6,8 @@ import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.argamap import com.lagradost.cloudstream3.extractors.helper.GogoHelper import com.lagradost.cloudstream3.mvvm.safeApiCall +import com.lagradost.cloudstream3.utils.AppUtils +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.SubtitleHelper @@ -146,20 +148,19 @@ object AnichiExtractors : Anichi() { ), referer = "$marinHost/anime", ).cookies.let { - it["XSRF-TOKEN"] to it["marin_session"] + decode(it["XSRF-TOKEN"].toString()) to decode(it["marin_session"].toString()) } - app.get( + val json = app.get( url, headers = mapOf( - "Referer" to "$marinHost/", - "Cookie" to "__ddg1=;__ddg2_=; XSRF-TOKEN=${cookies.first}; marin_session=${cookies.second};", - "x-inertia" to "true", - "x-inertia-version" to "5ee7503af8c9844b1e8d34466b727694", - "X-Requested-With" to "XMLHttpRequest", - "X-XSRF-TOKEN" to decode(cookies.first.toString()) - ) - ).parsedSafe()?.props?.video?.data?.mirror?.map { video -> + "Accept" to "text/html, application/xhtml+xml", + "Cookie" to "__ddg1=;__ddg2_=;XSRF-TOKEN=${cookies.first};marin_session=${cookies.second};", + "X-XSRF-TOKEN" to cookies.first + ), + referer = "$marinHost/anime/$id" + ).document.selectFirst("div#app")?.attr("data-page") + tryParseJson(json)?.props?.video?.data?.mirror?.map { video -> callback.invoke( ExtractorLink( "Marin", diff --git a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt index a757305d..ab50f5b4 100644 --- a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt +++ b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt @@ -3,6 +3,7 @@ package com.hexated import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.extractors.XStreamCdn +import com.lagradost.cloudstream3.utils.AppUtils import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName @@ -60,9 +61,7 @@ open class DramaidProvider : MainAPI() { private fun Element.toSearchResult(): SearchResponse? { val href = getProperDramaLink(this.selectFirst("a.tip")!!.attr("href")) val title = this.selectFirst("h2[itemprop=headline]")?.text()?.trim() ?: return null - val posterUrl = fixUrlNull( - this.selectFirst("noscript img")?.attr("src") ?: this.selectFirst("img")?.attr("src") - ) + val posterUrl = fixUrlNull(this.select("img:last-child").attr("src")) return newTvSeriesSearchResponse(title, href, TvType.AsianDrama) { this.posterUrl = posterUrl @@ -80,7 +79,7 @@ open class DramaidProvider : MainAPI() { val document = app.get(url).document val title = document.selectFirst("h1.entry-title")?.text()?.trim() ?: "" - val poster = fixUrlNull(document.selectFirst("div.thumb noscript img")?.attr("src") ?: document.selectFirst("div.thumb img")?.attr("src")) + val poster = fixUrlNull(document.select("div.thumb img:last-child").attr("src")) val tags = document.select(".genxed > a").map { it.text() } val type = document.selectFirst(".info-content .spe span:contains(Tipe:)")?.ownText() val year = Regex("\\d, ([0-9]*)").find( diff --git a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt index 7912713c..08bf2b87 100644 --- a/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt +++ b/Gomov/src/main/kotlin/com/hexated/DutaMovie.kt @@ -5,7 +5,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.httpsify import com.lagradost.cloudstream3.utils.loadExtractor -class DutaMovie : Gomov() { +open class DutaMovie : Gomov() { override var mainUrl = "https://dutamovie21.live" override var name = "DutaMovie" diff --git a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt index b3043cb7..bd11fd67 100644 --- a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt +++ b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt @@ -12,6 +12,7 @@ class GomovPlugin: Plugin() { registerMainAPI(Gomov()) registerMainAPI(DutaMovie()) registerMainAPI(Ngefilm()) + registerMainAPI(Nodrakorid()) registerExtractorAPI(Filelions()) registerExtractorAPI(Likessb()) registerExtractorAPI(DbGdriveplayer()) diff --git a/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt b/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt index 7c4be51f..00c20195 100644 --- a/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt +++ b/Gomov/src/main/kotlin/com/hexated/Ngefilm.kt @@ -8,7 +8,7 @@ import com.lagradost.cloudstream3.mainPageOf import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor -class Ngefilm : Gomov() { +class Ngefilm : DutaMovie() { override var mainUrl = "https://ngefilm21.lol" override var name = "Ngefilm" @@ -19,22 +19,4 @@ class Ngefilm : Gomov() { "/page/%d/?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=indonesia&quality=" to "Series Indonesia", ) - override suspend fun loadLinks( - data: String, - isCasting: Boolean, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit - ): Boolean { - - val document = app.get(data).document - document.select("ul.muvipro-player-tabs li a").apmap { server -> - val iframe = app.get(fixUrl(server.attr("href"))).document.selectFirst("div.gmr-embed-responsive iframe") - ?.attr("src")?.let { fixUrl(it) } ?: return@apmap - loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback) - } - - return true - - } - } \ No newline at end of file diff --git a/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt b/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt new file mode 100644 index 00000000..1e383927 --- /dev/null +++ b/Gomov/src/main/kotlin/com/hexated/Nodrakorid.kt @@ -0,0 +1,16 @@ +package com.hexated + +import com.lagradost.cloudstream3.mainPageOf + +class Nodrakorid : DutaMovie() { + override var mainUrl = "https://no-drak-or.xyz" + override var name = "Nodrakorid" + + override val mainPage = mainPageOf( + "genre/movie/page/%d/" to "Film Terbaru", + "genre/korean-movie/page/%d/" to "Film Korea", + "genre/drama/page/%d/" to "Drama Korea", + "genre/c-drama/c-drama-c-drama/page/%d/" to "Drama China", + "genre/thai-drama/page/%d/" to "Drama Thailand", + ) +} \ No newline at end of file From 41d94d1810ea237976f6b765046b638f3e13a1a8 Mon Sep 17 00:00:00 2001 From: Hexated <37908684+hexated@users.noreply.github.com> Date: Sat, 22 Jul 2023 23:40:21 +0700 Subject: [PATCH 17/22] Update build.gradle.kts --- Gomov/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts index 71e8c9c4..326a8138 100644 --- a/Gomov/build.gradle.kts +++ b/Gomov/build.gradle.kts @@ -6,7 +6,7 @@ cloudstream { language = "id" // All of these properties are optional, you can safely remove them - description = "Include: DutaMovie, Ngefilm" + description = "Include: DutaMovie, Ngefilm, Nodrakorid" authors = listOf("Hexated") /** From e4597d95671566f8b2f1a4ddc9d24c91b9f6beb5 Mon Sep 17 00:00:00 2001 From: hexated Date: Sun, 23 Jul 2023 01:20:33 +0700 Subject: [PATCH 18/22] small fix --- Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt b/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt index 0656e2d2..2c34e9f7 100644 --- a/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt +++ b/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt @@ -87,6 +87,7 @@ private val embedBlackList = listOf( "https://videobin.co/", "https://ok.ru", "https://streamlare.com", + "https://filemoon", "streaming.php", ) From f38a602b972cb4a1ddeeb3453d55f7087ea15cd2 Mon Sep 17 00:00:00 2001 From: hexated Date: Mon, 24 Jul 2023 01:05:02 +0700 Subject: [PATCH 19/22] sora: fix upcloud,vidcloud, aniwatch --- SoraStream/build.gradle.kts | 2 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 27 +++++++++---------- .../src/main/kotlin/com/hexated/SoraParser.kt | 6 ++--- .../src/main/kotlin/com/hexated/SoraStream.kt | 3 +-- .../src/main/kotlin/com/hexated/SoraUtils.kt | 27 ++++++++++++++----- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index f035b3fd..0e7ce60e 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 = 145 +version = 146 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index ad127d88..63d46655 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -930,7 +930,7 @@ object SoraExtractor : SoraStream() { argamap( { - invokeZoro(aniId, episode, subtitleCallback, callback) + invokeAniwatch(malId, episode, subtitleCallback, callback) }, { invokeAnimeKaizoku(malId, epsTitle, season, episode, callback) @@ -1004,28 +1004,26 @@ object SoraExtractor : SoraStream() { } - private suspend fun invokeZoro( - aniId: Int? = null, + private suspend fun invokeAniwatch( + malId: Int? = null, episode: Int? = null, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ) { - val animeId = - app.get("https://raw.githubusercontent.com/MALSync/MAL-Sync-Backup/master/data/anilist/anime/${aniId ?: return}.json") - .parsedSafe()?.pages?.zoro?.keys?.map { it } val headers = mapOf( "X-Requested-With" to "XMLHttpRequest", ) + val animeId = app.get("$malsyncAPI/mal/anime/${malId ?: return}").parsedSafe()?.sites?.zoro?.keys?.map { it } animeId?.apmap { id -> - val episodeId = app.get("$zoroAPI/ajax/episode/list/${id ?: return@apmap}", headers = headers) - .parsedSafe()?.html?.let { + val episodeId = app.get("$aniwatchAPI/ajax/v2/episode/list/${id ?: return@apmap}", headers = headers) + .parsedSafe()?.html?.let { Jsoup.parse(it) }?.select("div.ss-list a")?.find { it.attr("data-number") == "${episode ?: 1}" } ?.attr("data-id") val servers = - app.get("$zoroAPI/ajax/episode/servers?episodeId=${episodeId ?: return@apmap}", headers = headers) - .parsedSafe()?.html?.let { Jsoup.parse(it) } + app.get("$aniwatchAPI/ajax/v2/episode/servers?episodeId=${episodeId ?: return@apmap}", headers = headers) + .parsedSafe()?.html?.let { Jsoup.parse(it) } ?.select("div.item.server-item")?.map { Triple( it.text(), @@ -1035,22 +1033,21 @@ object SoraExtractor : SoraStream() { } servers?.apmap servers@{ server -> - val iframe = - app.get("$zoroAPI/ajax/episode/sources?id=${server.second ?: return@servers}", headers = headers) - .parsedSafe()?.link ?: return@servers + val iframe = app.get("$aniwatchAPI/ajax/v2/episode/sources?id=${server.second ?: return@servers}", headers = headers) + .parsedSafe()?.link ?: return@servers val audio = if (server.third == "sub") "Raw" else "English Dub" if (server.first.contains(Regex("Vidstreaming|MegaCloud|Vidcloud"))) { extractRabbitStream( "${server.first} [$audio]", iframe, - "$zoroAPI/", + "$aniwatchAPI/", subtitleCallback, callback, false, decryptKey = RabbitStream.getZoroKey() ) { it } } else { - loadExtractor(iframe, "$zoroAPI/", subtitleCallback, callback) + loadExtractor(iframe, "$aniwatchAPI/", subtitleCallback, callback) } } diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt index 9646b846..ee85e838 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt @@ -405,15 +405,15 @@ data class CrunchyrollSourcesResponses( @JsonProperty("meta") val meta: CrunchyrollMeta? = null, ) -data class MALSyncPages( +data class MALSyncSites( @JsonProperty("Zoro") val zoro: HashMap>? = hashMapOf(), ) data class MALSyncResponses( - @JsonProperty("Pages") val pages: MALSyncPages? = null, + @JsonProperty("Sites") val sites: MALSyncSites? = null, ) -data class ZoroResponses( +data class AniwatchResponses( @JsonProperty("html") val html: String? = null, @JsonProperty("link") val link: String? = null, ) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index e0744b10..aab30a60 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -16,7 +16,6 @@ import com.hexated.SoraExtractor.invokeMovieHab import com.hexated.SoraExtractor.invokeNoverse import com.hexated.SoraExtractor.invokeSeries9 import com.hexated.SoraExtractor.invokeVidSrc -import com.hexated.SoraExtractor.invokeXmovies import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.metaproviders.TmdbProvider @@ -100,7 +99,7 @@ open class SoraStream : TmdbProvider() { const val filmxyAPI = "https://www.filmxy.vip" const val kimcartoonAPI = "https://kimcartoon.li" const val xMovieAPI = "https://xemovies.to" - const val zoroAPI = "https://kaido.to" + const val aniwatchAPI = "https://aniwatch.to" const val crunchyrollAPI = "https://beta-api.crunchyroll.com" const val kissKhAPI = "https://kisskh.co" const val lingAPI = "https://ling-online.net" diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index 38416433..8db8f4f4 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -21,6 +21,7 @@ import com.lagradost.cloudstream3.APIHolder.getCaptchaToken import com.lagradost.cloudstream3.APIHolder.unixTimeMS import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.Coroutines.ioSafe @@ -578,7 +579,7 @@ suspend fun invokeSmashyIm( Regex("['\"]?subtitle['\"]?:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1) ?: return M3u8Helper.generateM3u8( - name, + "Smashy [$name]", sources, "" ).forEach(callback) @@ -955,7 +956,7 @@ suspend fun searchWatchOnline( } //modified code from https://github.com/jmir1/aniyomi-extensions/blob/master/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/AccessTokenInterceptor.kt -fun getCrunchyrollToken(): Map { +suspend fun getCrunchyrollToken(): Map { val client = app.baseClient.newBuilder() .proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress("cr-unblocker.us.to", 1080))) .build() @@ -975,7 +976,7 @@ fun getCrunchyrollToken(): Map { "Authorization" to "Basic ${BuildConfig.CRUNCHYROLL_BASIC_TOKEN}" ), data = mapOf( - "refresh_token" to BuildConfig.CRUNCHYROLL_REFRESH_TOKEN, + "refresh_token" to app.get(BuildConfig.CRUNCHYROLL_REFRESH_TOKEN).text, "grant_type" to "refresh_token", "scope" to "offline_access" ) @@ -1840,8 +1841,8 @@ object RabbitStream { if (sources == null || encryptedMap.encrypted == false) { response.parsedSafe() } else { - val decrypted = - decryptMapped>(sources, decryptKey) + val (realKey, encData) = extractRealKey(sources, decryptKey) + val decrypted = decryptMapped>(encData, realKey) SourceObject( sources = decrypted, tracks = encryptedMap.tracks @@ -1984,7 +1985,21 @@ object RabbitStream { } suspend fun getZoroKey(): String { - return app.get("https://raw.githubusercontent.com/enimax-anime/key/e0/key.txt").text + return app.get("https://raw.githubusercontent.com/enimax-anime/key/e6/key.txt").text + } + + private fun extractRealKey(originalString: String?, stops: String) : Pair { + val table = parseJson>>(stops) + val decryptedKey = StringBuilder() + var offset = 0 + var encryptedString = originalString + + table.forEach { (start, end) -> + decryptedKey.append(encryptedString?.substring(start - offset, end - offset)) + encryptedString = encryptedString?.substring(0, start - offset) + encryptedString?.substring(end - offset) + offset += end - start + } + return decryptedKey.toString() to encryptedString.toString() } private inline fun decryptMapped(input: String, key: String): T? { From 22b5f99e48a0bda4dbe7b644c214a7e6de186031 Mon Sep 17 00:00:00 2001 From: hexated Date: Mon, 24 Jul 2023 01:08:26 +0700 Subject: [PATCH 20/22] sora: disable animeKaizoku --- SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 63d46655..6d75648a 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -932,9 +932,6 @@ object SoraExtractor : SoraStream() { { invokeAniwatch(malId, episode, subtitleCallback, callback) }, - { - invokeAnimeKaizoku(malId, epsTitle, season, episode, callback) - }, { invokeBiliBili(aniId, episode, subtitleCallback, callback) }, From c1d59c7f8e727e40df7c61bc214051922e8079da Mon Sep 17 00:00:00 2001 From: hexated Date: Mon, 24 Jul 2023 21:25:57 +0700 Subject: [PATCH 21/22] sora: fixed ask4movies --- Nimegami/build.gradle.kts | 27 +++ Nimegami/src/main/AndroidManifest.xml | 2 + .../src/main/kotlin/com/hexated/Extractors.kt | 60 ++++++ .../src/main/kotlin/com/hexated/Nimegami.kt | 197 ++++++++++++++++++ .../main/kotlin/com/hexated/NimegamiPlugin.kt | 15 ++ NontonAnimeIDProvider/build.gradle.kts | 2 +- .../com/hexated/NontonAnimeIDProvider.kt | 2 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 10 +- .../src/main/kotlin/com/hexated/SoraParser.kt | 8 +- .../src/main/kotlin/com/hexated/SoraStream.kt | 2 +- .../src/main/kotlin/com/hexated/SoraUtils.kt | 2 +- .../src/main/kotlin/com/hexated/Extractors.kt | 37 ---- .../com/hexated/YomoviesProviderPlugin.kt | 1 - 13 files changed, 316 insertions(+), 49 deletions(-) create mode 100644 Nimegami/build.gradle.kts create mode 100644 Nimegami/src/main/AndroidManifest.xml create mode 100644 Nimegami/src/main/kotlin/com/hexated/Extractors.kt create mode 100644 Nimegami/src/main/kotlin/com/hexated/Nimegami.kt create mode 100644 Nimegami/src/main/kotlin/com/hexated/NimegamiPlugin.kt delete mode 100644 YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt diff --git a/Nimegami/build.gradle.kts b/Nimegami/build.gradle.kts new file mode 100644 index 00000000..82d96dc1 --- /dev/null +++ b/Nimegami/build.gradle.kts @@ -0,0 +1,27 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + language = "id" + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + authors = listOf("Hexated") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + tvTypes = listOf( + "AnimeMovie", + "Anime", + "OVA", + ) + + iconUrl = "https://www.google.com/s2/favicons?domain=nimegami.id&sz=%size%" +} \ No newline at end of file diff --git a/Nimegami/src/main/AndroidManifest.xml b/Nimegami/src/main/AndroidManifest.xml new file mode 100644 index 00000000..c98063f8 --- /dev/null +++ b/Nimegami/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Nimegami/src/main/kotlin/com/hexated/Extractors.kt b/Nimegami/src/main/kotlin/com/hexated/Extractors.kt new file mode 100644 index 00000000..aed3ac15 --- /dev/null +++ b/Nimegami/src/main/kotlin/com/hexated/Extractors.kt @@ -0,0 +1,60 @@ +package com.hexated + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities + +open class Mitedrive : ExtractorApi() { + override val name = "Mitedrive" + override val mainUrl = "https://mitedrive.com" + override val requiresReferer = false + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val id = url.substringAfterLast("/") + val video = app.post( + "$mainUrl/api/generate", + referer = "$mainUrl/", + data = mapOf( + "short_url" to id + ) + ).parsedSafe()?.data?.url + + val headers = mapOf( + "Accept" to "*/*", + "Connection" to "keep-alive", + "Sec-Fetch-Dest" to "empty", + "Sec-Fetch-Mode" to "cors", + "Sec-Fetch-Site" to "cross-site", + "Origin" to mainUrl, + ) + + callback.invoke( + ExtractorLink( + this.name, + this.name, + video ?: return, + "$mainUrl/", + Qualities.Unknown.value, + headers = headers + ) + ) + + } + + data class Data( + @JsonProperty("url") val url: String? = null, + ) + + data class Responses( + @JsonProperty("data") val data: Data? = null, + ) + +} \ No newline at end of file diff --git a/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt b/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt new file mode 100644 index 00000000..69541e2e --- /dev/null +++ b/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt @@ -0,0 +1,197 @@ +package com.hexated + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import org.jsoup.nodes.Element +import org.jsoup.select.Elements +import java.net.URI + +class Nimegami : MainAPI() { + override var mainUrl = "https://nimegami.id" + override var name = "Nimegami" + override val hasMainPage = true + override var lang = "id" + override val supportedTypes = setOf( + TvType.Anime, + TvType.AnimeMovie, + TvType.OVA + ) + + companion object { + fun getType(t: String): TvType { + return if (t.contains("OVA", true) || t.contains("Special", true)) TvType.OVA + else if (t.contains("Movie", true)) TvType.AnimeMovie + else TvType.Anime + } + + fun getStatus(t: String?): ShowStatus { + return when { + t?.contains("On-Going", true) == true -> ShowStatus.Ongoing + else -> ShowStatus.Completed + } + } + } + + override val mainPage = mainPageOf( + "" to "Updated Anime", + "/type/tv" to "Anime", + "/type/movie" to "Movie", + "/type/ona" to "ONA", + "/type/live-action" to "Live Action", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val document = app.get("$mainUrl${request.data}/page/$page").document + val home = document.select("div.post-article article, div.archive article").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse( + list = HomePageList( + name = request.name, + list = home, + isHorizontalImages = request.name != "Updated Anime" + ), + hasNext = true + ) + } + + private fun Element.toSearchResult(): AnimeSearchResponse? { + val href = fixUrl(this.selectFirst("a")!!.attr("href")) + val title = this.selectFirst("h2 a")?.text() ?: return null + val posterUrl = (this.selectFirst("noscript img") ?: this.selectFirst("img"))?.attr("src") + val episode = this.selectFirst("ul li:contains(Episode), div.eps-archive")?.ownText() + ?.filter { it.isDigit() }?.toIntOrNull() + + return newAnimeSearchResponse(title, href, TvType.Anime) { + this.posterUrl = posterUrl + addSub(episode) + } + + } + + override suspend fun search(query: String): List { + return app.get("$mainUrl/?s=$query&post_type=post").document.select("div.archive article") + .mapNotNull { + it.toSearchResult() + } + } + + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + + val table = document.select("div#Info table tbody") + val title = table.getContent("Judul :").text() + val poster = document.selectFirst("div.coverthumbnail img")?.attr("src") + val bgPoster = document.selectFirst("div.thumbnail-a img")?.attr("src") + val tags = table.getContent("Kategori").select("a").map { it.text() } + + val year = table.getContent("Musim / Rilis").text().filter { it.isDigit() }.toIntOrNull() + val status = getStatus(document.selectFirst("h1[itemprop=headline]")?.text()) + val type = table.getContent("Type").text() + val description = document.select("div#Sinopsis p").text().trim() + + + val episodes = document.select("div.list_eps_stream li") + .mapNotNull { + val name = it.text() + val link = it.attr("data") + Episode(link, name) + } + + val recommendations = document.select("div#randomList > a").mapNotNull { + val epHref = it.attr("href") + val epTitle = it.select("h5.sidebar-title-h5.px-2.py-2").text() + val epPoster = it.select(".product__sidebar__view__item.set-bg").attr("data-setbg") + + newAnimeSearchResponse(epTitle, epHref, TvType.Anime) { + this.posterUrl = epPoster + addDubStatus(dubExist = false, subExist = true) + } + } + + return newAnimeLoadResponse(title, url, getType(type)) { + engName = title + posterUrl = poster + backgroundPosterUrl = bgPoster + this.year = year + addEpisodes(DubStatus.Subbed, episodes) + showStatus = status + plot = description + this.tags = tags + this.recommendations = recommendations + } + + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + tryParseJson>(base64Decode(data))?.map { sources -> + sources.url?.apmap { url -> + loadFixedExtractor(url.fixIframe(), sources.format, "$mainUrl/", subtitleCallback, callback) + } + } + + return true + } + + private suspend fun loadFixedExtractor( + url: String, + quality: String?, + referer: String? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + loadExtractor(url, referer, subtitleCallback) { link -> + callback.invoke( + ExtractorLink( + link.name, + link.name, + link.url, + link.referer, + getQualityFromName(quality), + link.isM3u8, + link.headers, + link.extractorData + ) + ) + } + } + + private fun getBaseUrl(url: String): String { + return URI(url).let { + "${it.scheme}://${it.host}" + } + } + + private fun Elements.getContent(css: String) : Elements { + return this.select("tr:contains($css) td:last-child") + } + + private fun String.fixIframe() : String { + val url = base64Decode(this.substringAfter("url=").substringAfter("id=")) + val host = getBaseUrl(url) + return when { + url.contains("hxfile") -> { + val id = url.substringAfterLast("/") + "$host/embed-$id.html" + } + else -> fixUrl(url) + } + } + + data class Sources( + @JsonProperty("format") val format: String? = null, + @JsonProperty("url") val url: ArrayList? = arrayListOf(), + ) + +} diff --git a/Nimegami/src/main/kotlin/com/hexated/NimegamiPlugin.kt b/Nimegami/src/main/kotlin/com/hexated/NimegamiPlugin.kt new file mode 100644 index 00000000..8ab01378 --- /dev/null +++ b/Nimegami/src/main/kotlin/com/hexated/NimegamiPlugin.kt @@ -0,0 +1,15 @@ + +package com.hexated + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class NimegamiPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(Nimegami()) + registerExtractorAPI(Mitedrive()) + } +} \ No newline at end of file diff --git a/NontonAnimeIDProvider/build.gradle.kts b/NontonAnimeIDProvider/build.gradle.kts index 3da1506d..cff263d4 100644 --- a/NontonAnimeIDProvider/build.gradle.kts +++ b/NontonAnimeIDProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 15 +version = 16 cloudstream { diff --git a/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt b/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt index aa54f212..2912e7a2 100644 --- a/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt +++ b/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt @@ -11,7 +11,7 @@ import org.jsoup.nodes.Element import java.net.URI class NontonAnimeIDProvider : MainAPI() { - override var mainUrl = "https://nontonanimeid.bio" + override var mainUrl = "https://nontonanimeid.lol" override var name = "NontonAnimeID" override val hasQuickSearch = false override val hasMainPage = true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 6d75648a..8b3819d5 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -2695,7 +2695,15 @@ object SoraExtractor : SoraStream() { epsDoc.select("ul.group-links-list li:nth-child($episode) a").attr("data-embed-src") } - loadExtractor(iframe, ask4MoviesAPI, subtitleCallback, callback) + val iframeDoc = app.get(iframe, referer = "$ask4MoviesAPI/").text + val script = Regex("""eval\(function\(p,a,c,k,e,.*\)\)""").findAll(iframeDoc).lastOrNull()?.value + val unpacked = getAndUnpack(script ?: return) + val m3u8 = Regex("file:\\s*\"(.*?m3u8.*?)\"").find(unpacked)?.groupValues?.getOrNull(1) + M3u8Helper.generateM3u8( + "Ask4movie", + m3u8 ?: return, + mainUrl + ).forEach(callback) } diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt index ee85e838..a1e91094 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt @@ -336,16 +336,12 @@ data class VizcloudSources( @JsonProperty("file") val file: String? = null, ) -data class VizcloudMedia( +data class VizcloudResult( @JsonProperty("sources") val sources: ArrayList? = arrayListOf(), ) -data class VizcloudData( - @JsonProperty("media") val media: VizcloudMedia? = null, -) - data class VizcloudResponses( - @JsonProperty("data") val data: VizcloudData? = null, + @JsonProperty("result") val result: VizcloudResult? = null, ) data class AnilistExternalLinks( diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index aab30a60..16d00b6b 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -119,7 +119,7 @@ open class SoraStream : TmdbProvider() { const val smashyStreamAPI = "https://embed.smashystream.com" const val watchSomuchAPI = "https://watchsomuch.tv" // sub only val gomoviesAPI = base64DecodeAPI("bQ==Y28=ZS4=aW4=bmw=LW8=ZXM=dmk=bW8=Z28=Ly8=czo=dHA=aHQ=") - const val ask4MoviesAPI = "https://ask4movie.net" + const val ask4MoviesAPI = "https://ask4movie.nl" const val biliBiliAPI = "https://api-vn.otakuz.live/server" const val watchOnlineAPI = "https://watchonline.ag" const val nineTvAPI = "https://api.9animetv.live" diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index 8db8f4f4..5f2ae0fd 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -418,7 +418,7 @@ suspend fun invokeVizcloud( ) { val id = Regex("(?:/embed[-/]|/e/)([^?/]*)").find(url)?.groupValues?.getOrNull(1) app.get("$consumetHelper?query=${id ?: return}&action=vizcloud") - .parsedSafe()?.data?.media?.sources?.map { + .parsedSafe()?.result?.sources?.map { M3u8Helper.generateM3u8( "Vizcloud", it.file ?: return@map, diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt b/YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt deleted file mode 100644 index 08597bf1..00000000 --- a/YomoviesProvider/src/main/kotlin/com/hexated/Extractors.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.hexated - -import com.fasterxml.jackson.annotation.JsonProperty -import com.lagradost.cloudstream3.SubtitleFile -import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.extractors.SpeedoStream -import com.lagradost.cloudstream3.utils.AppUtils -import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.M3u8Helper -import com.lagradost.cloudstream3.utils.getAndUnpack - -class Streamoupload : SpeedoStream() { - override val mainUrl = "https://streamoupload.xyz" - override val name = "Streamoupload" - - override suspend fun getUrl( - url: String, - referer: String?, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit - ) { - val script = getAndUnpack(app.get(url, referer = referer).text) - val data = script.substringAfter("sources:[") - .substringBefore("],").replace("file", "\"file\"").trim() - AppUtils.tryParseJson(data)?.let { - M3u8Helper.generateM3u8( - name, - it.file, - "$mainUrl/", - ).forEach(callback) - } - } - - private data class File( - @JsonProperty("file") val file: String, - ) -} \ No newline at end of file diff --git a/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt b/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt index 60bb8004..45bf3e5a 100644 --- a/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt +++ b/YomoviesProvider/src/main/kotlin/com/hexated/YomoviesProviderPlugin.kt @@ -11,6 +11,5 @@ class YomoviesProviderPlugin: Plugin() { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(YomoviesProvider()) registerMainAPI(Watchomovies()) - registerExtractorAPI(Streamoupload()) } } \ No newline at end of file From 839ec22f6768e24dbb058c66cef283e992a1d0dc Mon Sep 17 00:00:00 2001 From: hexated Date: Mon, 24 Jul 2023 21:26:12 +0700 Subject: [PATCH 22/22] sora: fixed ask4movies --- SoraStream/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 0e7ce60e..cc49bd00 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 = 146 +version = 147 android { defaultConfig {