From ddc24331c4c47a938f4b8b737b50d8d50ef328e6 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 10 Jul 2023 22:45:32 +0700 Subject: [PATCH 01/16] bump --- Ngefilm/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/Extractors.kt | 34 --------------- OploverzProvider/build.gradle.kts | 2 +- .../kotlin/com/hexated/OploverzProvider.kt | 29 ------------- Samehadaku/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/Extractors.kt | 43 ------------------- .../kotlin/com/hexated/SamehadakuPlugin.kt | 2 - 7 files changed, 3 insertions(+), 111 deletions(-) delete mode 100644 Samehadaku/src/main/kotlin/com/hexated/Extractors.kt diff --git a/Ngefilm/build.gradle.kts b/Ngefilm/build.gradle.kts index d8eb0226..3187c097 100644 --- a/Ngefilm/build.gradle.kts +++ b/Ngefilm/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 2 +version = 3 cloudstream { diff --git a/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt b/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt index 9730276b..d3171f0c 100644 --- a/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt +++ b/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt @@ -15,40 +15,6 @@ import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.PBEKeySpec import javax.crypto.spec.SecretKeySpec -class Dooood : DoodLaExtractor() { - override var mainUrl = "https://dooood.com" -} - -class Guccihide : Filesim() { - override val name = "Guccihide" - override var mainUrl = "https://guccihide.com" -} - -class Ahvsh : Filesim() { - override val name = "Ahvsh" - override var mainUrl = "https://ahvsh.com" -} - -class Lvturbo : StreamSB() { - override var name = "Lvturbo" - override var mainUrl = "https://lvturbo.com" -} - -class Sbrapid : StreamSB() { - override var name = "Sbrapid" - override var mainUrl = "https://sbrapid.com" -} - -class Sbface : StreamSB() { - override var name = "Sbface" - override var mainUrl = "https://sbface.com" -} - -class Sbsonic : StreamSB() { - override var name = "Sbsonic" - override var mainUrl = "https://sbsonic.com" -} - object LocalServer { private const val KEY = "4VqE3#N7zt&HEP^a" diff --git a/OploverzProvider/build.gradle.kts b/OploverzProvider/build.gradle.kts index 5c4494a5..49f2737c 100644 --- a/OploverzProvider/build.gradle.kts +++ b/OploverzProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 19 +version = 20 cloudstream { diff --git a/OploverzProvider/src/main/kotlin/com/hexated/OploverzProvider.kt b/OploverzProvider/src/main/kotlin/com/hexated/OploverzProvider.kt index 65836dd1..95d5bcab 100644 --- a/OploverzProvider/src/main/kotlin/com/hexated/OploverzProvider.kt +++ b/OploverzProvider/src/main/kotlin/com/hexated/OploverzProvider.kt @@ -220,32 +220,3 @@ class OploverzProvider : MainAPI() { } } - -class Streamhide : Filesim() { - override val mainUrl = "https://streamhide.to" - override val name = "Streamhide" -} - -open class Pixeldrain : ExtractorApi() { - override val name = "Pixeldrain" - override val mainUrl = "https://pixeldrain.com" - override val requiresReferer = false - override suspend fun getUrl( - url: String, - referer: String?, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit - ) { - val mId = Regex("/([ul]/[\\da-zA-Z\\-]+)").find(url)?.groupValues?.get(1)?.split("/") - callback.invoke( - ExtractorLink( - this.name, - this.name, - "$mainUrl/api/file/${mId?.last() ?: return}?download", - url, - Qualities.Unknown.value, - ) - ) - } - -} diff --git a/Samehadaku/build.gradle.kts b/Samehadaku/build.gradle.kts index 4e5c21b1..a262ac5b 100644 --- a/Samehadaku/build.gradle.kts +++ b/Samehadaku/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 10 +version = 11 cloudstream { diff --git a/Samehadaku/src/main/kotlin/com/hexated/Extractors.kt b/Samehadaku/src/main/kotlin/com/hexated/Extractors.kt deleted file mode 100644 index f0b6db8f..00000000 --- a/Samehadaku/src/main/kotlin/com/hexated/Extractors.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.hexated - -import com.lagradost.cloudstream3.SubtitleFile -import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.extractors.XStreamCdn -import com.lagradost.cloudstream3.utils.ExtractorApi -import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.Qualities -import java.net.URI - -class Suzihaza: XStreamCdn() { - override val name: String = "Suzihaza" - override val mainUrl: String = "https://suzihaza.com" -} - -open class Wibufile : ExtractorApi() { - override val name: String = "Wibufile" - override val mainUrl: String = "https://wibufile.com" - override val requiresReferer = false - - override suspend fun getUrl( - url: String, - referer: String?, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit - ) { - val res = app.get(url).text - val video = Regex("src: ['\"](.*?)['\"]").find(res)?.groupValues?.get(1) - - callback.invoke( - ExtractorLink( - name, - name, - video ?: return, - "$mainUrl/", - Qualities.Unknown.value, - URI(url).path.endsWith(".m3u8") - ) - ) - - } - -} \ No newline at end of file diff --git a/Samehadaku/src/main/kotlin/com/hexated/SamehadakuPlugin.kt b/Samehadaku/src/main/kotlin/com/hexated/SamehadakuPlugin.kt index 65e90137..307477b6 100644 --- a/Samehadaku/src/main/kotlin/com/hexated/SamehadakuPlugin.kt +++ b/Samehadaku/src/main/kotlin/com/hexated/SamehadakuPlugin.kt @@ -10,7 +10,5 @@ class SamehadakuPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(Samehadaku()) - registerExtractorAPI(Suzihaza()) - registerExtractorAPI(Wibufile()) } } \ No newline at end of file From 20dbd2a7745237d174e01aed7bd3cf509294884d Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 11 Jul 2023 19:07:22 +0700 Subject: [PATCH 02/16] fix few providers --- .../src/main/kotlin/com/hexated/Extractors.kt | 115 ------------------ .../src/main/kotlin/com/hexated/Ngefilm.kt | 14 +-- .../main/kotlin/com/hexated/NgefilmPlugin.kt | 7 -- .../com/hexated/OploverzProviderPlugin.kt | 2 - SoraStream/build.gradle.kts | 2 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 8 +- .../src/main/kotlin/com/hexated/SoraStream.kt | 22 ++-- .../main/kotlin/com/hexated/SoraStreamLite.kt | 20 +-- .../src/main/kotlin/com/hexated/SoraUtils.kt | 3 +- 9 files changed, 28 insertions(+), 165 deletions(-) delete mode 100644 Ngefilm/src/main/kotlin/com/hexated/Extractors.kt diff --git a/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt b/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt deleted file mode 100644 index d3171f0c..00000000 --- a/Ngefilm/src/main/kotlin/com/hexated/Extractors.kt +++ /dev/null @@ -1,115 +0,0 @@ -package com.hexated - -import com.fasterxml.jackson.annotation.JsonProperty -import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.extractors.DoodLaExtractor -import com.lagradost.cloudstream3.extractors.Filesim -import com.lagradost.cloudstream3.extractors.StreamSB -import com.lagradost.cloudstream3.utils.AppUtils -import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.Qualities -import java.net.URI -import javax.crypto.Cipher -import javax.crypto.SecretKeyFactory -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.PBEKeySpec -import javax.crypto.spec.SecretKeySpec - -object LocalServer { - private const val KEY = "4VqE3#N7zt&HEP^a" - - private fun getBaseUrl(url: String): String { - return URI(url).let { - "${it.scheme}://${it.host}" - } - } - - suspend fun getUrl( - url: String, - referer: String?, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit - ) { - val mainUrl = getBaseUrl(url) - val master = Regex("MasterJS\\s*=\\s*'([^']+)").find( - app.get( - url, - referer = referer - ).text - )?.groupValues?.get(1) - val encData = AppUtils.tryParseJson(base64Decode(master ?: return)) - val decrypt = cryptoAESHandler(encData ?: return, KEY, false) - - val source = Regex(""""?file"?:\s*"([^"]+)""").find(decrypt)?.groupValues?.get(1) - - // required - 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( - Ngefilm().name, - Ngefilm().name, - source ?: return, - "$mainUrl/", - Qualities.P1080.value, - headers = headers, - isM3u8 = true - ) - ) - - } - - private fun cryptoAESHandler( - data: AESData, - pass: String, - encrypt: Boolean = true - ): String { - val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512") - val spec = PBEKeySpec( - pass.toCharArray(), - data.salt?.hexToByteArray(), - data.iterations?.toIntOrNull() ?: 1, - 256 - ) - val key = factory.generateSecret(spec) - val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") - return if (!encrypt) { - cipher.init( - Cipher.DECRYPT_MODE, - SecretKeySpec(key.encoded, "AES"), - IvParameterSpec(data.iv?.hexToByteArray()) - ) - String(cipher.doFinal(base64DecodeArray(data.ciphertext.toString()))) - } else { - cipher.init( - Cipher.ENCRYPT_MODE, - SecretKeySpec(key.encoded, "AES"), - IvParameterSpec(data.iv?.hexToByteArray()) - ) - base64Encode(cipher.doFinal(data.ciphertext?.toByteArray())) - } - } - - private fun String.hexToByteArray(): ByteArray { - check(length % 2 == 0) { "Must have an even length" } - return chunked(2) - .map { it.toInt(16).toByte() } - - .toByteArray() - } - - data class AESData( - @JsonProperty("ciphertext") val ciphertext: String? = null, - @JsonProperty("iv") val iv: String? = null, - @JsonProperty("salt") val salt: String? = null, - @JsonProperty("iterations") val iterations: String? = null, - ) - -} \ 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 index 753f59c5..7e330489 100644 --- a/Ngefilm/src/main/kotlin/com/hexated/Ngefilm.kt +++ b/Ngefilm/src/main/kotlin/com/hexated/Ngefilm.kt @@ -19,14 +19,6 @@ class Ngefilm : MainAPI() { TvType.AsianDrama ) - companion object { - private val localServer = arrayOf( - "https://bestx.stream", - "https://chillx.top", - "https://watchx.top", - ) - } - 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", @@ -128,11 +120,7 @@ class Ngefilm : MainAPI() { 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 - if (localServer.any { iframe.startsWith(it) }) { - LocalServer.getUrl(iframe, "$mainUrl/", subtitleCallback, callback) - } else { - loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback) - } + loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback) } return true diff --git a/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt b/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt index cbf73937..8fc845f8 100644 --- a/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt +++ b/Ngefilm/src/main/kotlin/com/hexated/NgefilmPlugin.kt @@ -10,12 +10,5 @@ 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()) - registerExtractorAPI(Sbsonic()) - registerExtractorAPI(Sbface()) - registerExtractorAPI(Sbrapid()) - registerExtractorAPI(Lvturbo()) - registerExtractorAPI(Ahvsh()) - registerExtractorAPI(Guccihide()) - registerExtractorAPI(Dooood()) } } \ No newline at end of file diff --git a/OploverzProvider/src/main/kotlin/com/hexated/OploverzProviderPlugin.kt b/OploverzProvider/src/main/kotlin/com/hexated/OploverzProviderPlugin.kt index 4f313881..157869bd 100644 --- a/OploverzProvider/src/main/kotlin/com/hexated/OploverzProviderPlugin.kt +++ b/OploverzProvider/src/main/kotlin/com/hexated/OploverzProviderPlugin.kt @@ -10,7 +10,5 @@ class OploverzProviderPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(OploverzProvider()) - registerExtractorAPI(Streamhide()) - registerExtractorAPI(Pixeldrain()) } } \ No newline at end of file diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index e43f70eb..c770eba3 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 = 143 +version = 144 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 9b40016b..933475ca 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -960,7 +960,7 @@ object SoraExtractor : SoraStream() { ) { val res = app.get( "$biliBiliAPI/anime/episodes?id=${aniId ?: return}&source_id=bilibili", - referer = kaguyaBaseUrl + referer = otakuzBaseUrl ) .parsedSafe()?.episodes?.find { it.episodeNumber == episode @@ -969,7 +969,7 @@ object SoraExtractor : SoraStream() { val sources = app.get( "$biliBiliAPI/source?episode_id=${res.sourceEpisodeId}&source_media_id=${res.sourceMediaId}&source_id=${res.sourceId}", - referer = kaguyaBaseUrl + referer = otakuzBaseUrl ) .parsedSafe() @@ -977,7 +977,7 @@ object SoraExtractor : SoraStream() { val quality = app.get( source.file ?: return@apmap null, - referer = kaguyaBaseUrl + referer = otakuzBaseUrl ).document.selectFirst("Representation") ?.attr("height") callback.invoke( @@ -985,7 +985,7 @@ object SoraExtractor : SoraStream() { "BiliBili", "BiliBili", source.file, - kaguyaBaseUrl, + "", quality?.toIntOrNull() ?: Qualities.Unknown.value, isDash = true ) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 4687e7a9..e0744b10 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -121,7 +121,7 @@ open class SoraStream : TmdbProvider() { 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 biliBiliAPI = "https://api-vn.kaguya.app/server" + const val biliBiliAPI = "https://api-vn.otakuz.live/server" const val watchOnlineAPI = "https://watchonline.ag" const val nineTvAPI = "https://api.9animetv.live" const val putlockerAPI = "https://ww7.putlocker.vip" @@ -500,16 +500,16 @@ open class SoraStream : TmdbProvider() { { if(!res.isAnime) invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback) }, - { - invokeXmovies( - res.title, - res.year, - res.season, - res.episode, - subtitleCallback, - callback - ) - }, +// { +// invokeXmovies( +// res.title, +// res.year, +// res.season, +// res.episode, +// subtitleCallback, +// callback +// ) +// }, { if (!res.isAnime) invokeFmovies( res.title, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index 6f02e50a..dec99931 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -200,16 +200,16 @@ class SoraStreamLite : SoraStream() { callback ) }, - { - invokeXmovies( - res.title, - res.year, - res.season, - res.episode, - subtitleCallback, - callback - ) - }, +// { +// invokeXmovies( +// res.title, +// res.year, +// res.season, +// res.episode, +// subtitleCallback, +// callback +// ) +// }, { if (!res.isAnime) invokeFmovies( res.title, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index c47faa3b..524470c6 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -2,7 +2,6 @@ package com.hexated import android.util.Base64 import com.fasterxml.jackson.annotation.JsonProperty -import com.hexated.DumpUtils.createHeaders import com.hexated.DumpUtils.queryApi import com.hexated.SoraStream.Companion.anilistAPI import com.hexated.SoraStream.Companion.base64DecodeAPI @@ -51,7 +50,7 @@ import kotlin.math.min val bflixChipperKey = base64DecodeAPI("Yjc=ejM=TzA=YTk=WHE=WnU=bXU=RFo=") const val bflixKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -const val kaguyaBaseUrl = "https://kaguya.app/" +const val otakuzBaseUrl = "https://otakuz.live/" val soraHeaders = mapOf( "lang" to "en", "versioncode" to "33", From 1e272a089399caeac20b6ac5ef5d0bf961cb1a01 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 13 Jul 2023 13:27:01 +0700 Subject: [PATCH 03/16] fix some providers: Anichi, Layarkaca, Anroll, Movierulzhd --- Anichi/build.gradle.kts | 2 +- Anichi/src/main/kotlin/com/hexated/Anichi.kt | 120 +++++++++++++++--- Anroll/build.gradle.kts | 2 +- Anroll/src/main/kotlin/com/hexated/Anroll.kt | 8 +- LayarKacaProvider/build.gradle.kts | 2 +- .../kotlin/com/hexated/LayarKacaProvider.kt | 52 ++++---- .../com/hexated/LayarKacaProviderPlugin.kt | 1 + .../src/main/kotlin/com/hexated/Extractors.kt | 5 + .../kotlin/com/hexated/MovierulzhdPlugin.kt | 1 + 9 files changed, 143 insertions(+), 50 deletions(-) diff --git a/Anichi/build.gradle.kts b/Anichi/build.gradle.kts index 24eea240..103eac72 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 = 4 +version = 5 android { defaultConfig { diff --git a/Anichi/src/main/kotlin/com/hexated/Anichi.kt b/Anichi/src/main/kotlin/com/hexated/Anichi.kt index 02d0fe98..301fec66 100644 --- a/Anichi/src/main/kotlin/com/hexated/Anichi.kt +++ b/Anichi/src/main/kotlin/com/hexated/Anichi.kt @@ -2,12 +2,12 @@ package com.hexated import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.APIHolder.getTracker import com.lagradost.cloudstream3.LoadResponse.Companion.addActors import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.extractors.helper.GogoHelper +import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson @@ -32,14 +32,6 @@ class Anichi : MainAPI() { } } - private fun getType(t: String?): TvType { - return when { - t.equals("OVA", true) || t.equals("Special") -> TvType.OVA - t.equals("Movie", true) -> TvType.AnimeMovie - else -> TvType.Anime - } - } - override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie) private val popularTitle = "Popular" @@ -141,7 +133,6 @@ class Anichi : MainAPI() { val title = showData.name val description = showData.description val poster = showData.thumbnail - val type = getType(showData.type ?: "") val episodes = showData.availableEpisodesDetail.let { if (it == null) return@let Pair(null, null) @@ -164,13 +155,12 @@ class Anichi : MainAPI() { Pair(Actor(name, image), role) } - val names = showData.altNames?.plus(title)?.filterNotNull() ?: emptyList() - val trackers = getTracker(names, TrackerType.getTypes(type), showData.airedStart?.year) + val trackers = getTracker(title, showData.altNames?.firstOrNull(), showData.airedStart?.year, showData.season?.quarter, showData.type) return newAnimeLoadResponse(title ?: "", url, TvType.Anime) { engName = showData.altNames?.firstOrNull() - posterUrl = trackers?.image ?: poster - backgroundPosterUrl = trackers?.cover ?: showData.banner + posterUrl = trackers?.coverImage?.extraLarge ?: trackers?.coverImage?.large ?: poster + backgroundPosterUrl = trackers?.bannerImage ?: showData.banner rating = showData.averageScore?.times(100) tags = showData.genres year = showData.airedStart?.year @@ -184,8 +174,8 @@ class Anichi : MainAPI() { //this.recommendations = recommendations showStatus = getStatus(showData.status.toString()) - addMalId(trackers?.malId) - addAniListId(trackers?.aniId?.toIntOrNull()) + addMalId(trackers?.idMal) + addAniListId(trackers?.id) plot = description?.replace(Regex("""<(.*?)>"""), "") } } @@ -273,6 +263,14 @@ class Anichi : MainAPI() { isDash = server.resolutionStr == "Dash 1" ) ) + server.subtitles?.map { sub -> + subtitleCallback.invoke( + SubtitleFile( + SubtitleHelper.fromTwoLettersToLanguage(sub.lang ?: "") ?: sub.lang ?: "", + httpsify(sub.src ?: return@map) + ) + ) + } } } } @@ -315,7 +313,8 @@ class Anichi : MainAPI() { return meta.map { eps -> Episode( AnichiLoadData(id, lang, eps).toJson(), - "Ep $eps" + "Ep $eps", + episode = eps.toIntOrNull() ) }.reversed() } @@ -382,6 +381,69 @@ class Anichi : MainAPI() { } } + private suspend fun getTracker(name: String?, altName: String?, year: Int?, season: String?, type: String?): AniMedia? { + val ids = fetchId(name, year, season, type) + return if (ids?.id == null && ids?.idMal == null) fetchId( + altName, + year, + season, + type + ) else ids + } + + private suspend fun fetchId(title: String?, year: Int?, season: String?, type: String?): AniMedia? { + val query = """ + query ( + ${'$'}page: Int = 1 + ${'$'}search: String + ${'$'}sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC] + ${'$'}type: MediaType + ${'$'}season: MediaSeason + ${'$'}year: String + ${'$'}format: [MediaFormat] + ) { + Page(page: ${'$'}page, perPage: 20) { + media( + search: ${'$'}search + sort: ${'$'}sort + type: ${'$'}type + season: ${'$'}season + startDate_like: ${'$'}year + format_in: ${'$'}format + ) { + id + idMal + coverImage { extraLarge large } + bannerImage + } + } + } + """.trimIndent().trim() + + val variables = mapOf( + "search" to title, + "sort" to "SEARCH_MATCH", + "type" to "ANIME", + "season" to if(type.equals("ona", true)) "" else season?.uppercase(), + "year" to "$year%", + "format" to listOf(type?.uppercase()) + ).filterValues { value -> value != null && value.toString().isNotEmpty() } + + val data = mapOf( + "query" to query, + "variables" to variables + ).toJson().toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull()) + + return try { + app.post("https://graphql.anilist.co", requestBody = data) + .parsedSafe()?.data?.Page?.media?.firstOrNull() + } catch (t: Throwable) { + logError(t) + null + } + + } + companion object { private const val apiUrl = BuildConfig.ANICHI_API private const val serverUrl = BuildConfig.ANICHI_SERVER @@ -406,6 +468,30 @@ class Anichi : MainAPI() { val episode: String ) + data class CoverImage( + @JsonProperty("extraLarge") var extraLarge: String? = null, + @JsonProperty("large") var large: String? = null, + ) + + data class AniMedia( + @JsonProperty("id") var id: Int? = null, + @JsonProperty("idMal") var idMal: Int? = null, + @JsonProperty("coverImage") var coverImage: CoverImage? = null, + @JsonProperty("bannerImage") var bannerImage: String? = null, + ) + + data class AniPage( + @JsonProperty("media") var media: ArrayList = arrayListOf() + ) + + data class AniData( + @JsonProperty("Page") var Page: AniPage? = AniPage() + ) + + data class AniSearch( + @JsonProperty("data") var data: AniData? = AniData() + ) + data class AkIframe( @JsonProperty("idUrl") val idUrl: String? = null, ) diff --git a/Anroll/build.gradle.kts b/Anroll/build.gradle.kts index bbbb0839..7d575610 100644 --- a/Anroll/build.gradle.kts +++ b/Anroll/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { language = "pt-pt" diff --git a/Anroll/src/main/kotlin/com/hexated/Anroll.kt b/Anroll/src/main/kotlin/com/hexated/Anroll.kt index 178db598..d397caa0 100644 --- a/Anroll/src/main/kotlin/com/hexated/Anroll.kt +++ b/Anroll/src/main/kotlin/com/hexated/Anroll.kt @@ -35,7 +35,7 @@ class Anroll : MainAPI() { ): HomePageResponse { val document = app.get("$mainUrl/home").document val home = mutableListOf() - document.select("div.sc-f5d5b250-1.iJHcsI").map { div -> + document.select("div.hAbQAe").map { div -> val header = div.selectFirst("h2")?.text() ?: return@map val child = HomePageList( header, @@ -91,11 +91,11 @@ class Anroll : MainAPI() { val fixUrl = getProperAnimeLink(url) ?: throw ErrorLoadingException() val document = app.get(fixUrl).document - val article = document.selectFirst("article.sc-f5d5b250-9") ?: return null + val article = document.selectFirst("article.animedetails") ?: return null val title = article.selectFirst("h2")?.text() ?: return null - val poster = fixUrlNull(document.select("article.sc-f5d5b250-8 img").attr("src")) + val poster = fixUrlNull(document.select("section.animecontent img").attr("src")) val tags = article.select("div#generos a").map { it.text() } - val year = article.selectFirst("div.sc-f5d5b250-4")?.nextElementSibling()?.text() + val year = article.selectFirst("div.dfuefM")?.nextElementSibling()?.text() ?.toIntOrNull() val description = document.select("div.sinopse").text().trim() val type = if (fixUrl.contains("/a/")) TvType.Anime else TvType.AnimeMovie diff --git a/LayarKacaProvider/build.gradle.kts b/LayarKacaProvider/build.gradle.kts index 1f1549b9..b1cd5e23 100644 --- a/LayarKacaProvider/build.gradle.kts +++ b/LayarKacaProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 13 +version = 14 cloudstream { diff --git a/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProvider.kt b/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProvider.kt index 8b7c03a5..535214aa 100644 --- a/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProvider.kt +++ b/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProvider.kt @@ -6,11 +6,10 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.utils.* import org.jsoup.nodes.Element import java.net.URLDecoder -import java.net.URI class LayarKacaProvider : MainAPI() { - override var mainUrl = "https://d21.fun" - private var seriesUrl = "https://tv.nontondrama.click" + override var mainUrl = "https://tv.lk21official.pro" + private var seriesUrl = "https://tv1.nontondrama.click" override var name = "LayarKaca" override val hasMainPage = true override var lang = "id" @@ -57,7 +56,7 @@ class LayarKacaProvider : MainAPI() { private fun Element.toSearchResult(): SearchResponse? { val title = this.selectFirst("h1.grid-title > a")?.ownText()?.trim() ?: return null val href = fixUrl(this.selectFirst("a")!!.attr("href")) - val posterUrl = fixUrlNull(this.selectFirst(".grid-poster > a > img")?.attr("src")) + val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src")) val type = if (this.selectFirst("div.last-episode") == null) TvType.Movie else TvType.TvSeries return if (type == TvType.TvSeries) { @@ -176,33 +175,34 @@ class LayarKacaProvider : MainAPI() { it } } - invokeCast(link, callback) + loadExtractor(link, bananalicious, subtitleCallback, callback) } return true } - private suspend fun invokeCast( - url: String, - callback: (ExtractorLink) -> Unit - ) { - val response = app.get(url, referer = bananalicious).document - response.select("script[type=text/javascript]").map { script -> - if (script.data().contains(Regex("eval\\(function\\(p,a,c,k,e,[rd]"))) { - val unpackedscript = getAndUnpack(script.data()) - val m3u8Regex = Regex("file.\"(.*?m3u8.*?)\"") - val m3u8 = m3u8Regex.find(unpackedscript)?.destructured?.component1() ?: "" - if (m3u8.isNotEmpty()) { - M3u8Helper.generateM3u8( - fixTitle(URI(url).host).substringBefore("."), - m3u8, - mainUrl - ).forEach(callback) - } - } - } - } - private fun decode(input: String): String = URLDecoder.decode(input, "utf-8").replace(" ", "%20") } + +open class Emturbovid : ExtractorApi() { + override val name = "Emturbovid" + override val mainUrl = "https://emturbovid.com" + override val requiresReferer = true + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val response = app.get(url, referer = referer) + val m3u8 = Regex("[\"'](.*?master\\.m3u8.*?)[\"']").find(response.text)?.groupValues?.getOrNull(1) + M3u8Helper.generateM3u8( + name, + m3u8 ?: return, + mainUrl + ).forEach(callback) + } + +} diff --git a/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProviderPlugin.kt b/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProviderPlugin.kt index 9743b456..bd3389cb 100644 --- a/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProviderPlugin.kt +++ b/LayarKacaProvider/src/main/kotlin/com/hexated/LayarKacaProviderPlugin.kt @@ -10,5 +10,6 @@ class LayarKacaProviderPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(LayarKacaProvider()) + registerExtractorAPI(Emturbovid()) } } \ No newline at end of file diff --git a/Movierulzhd/src/main/kotlin/com/hexated/Extractors.kt b/Movierulzhd/src/main/kotlin/com/hexated/Extractors.kt index d30ef49b..87ae7b6d 100644 --- a/Movierulzhd/src/main/kotlin/com/hexated/Extractors.kt +++ b/Movierulzhd/src/main/kotlin/com/hexated/Extractors.kt @@ -11,6 +11,11 @@ import kotlin.random.Random const val twoEmbedAPI = "https://www.2embed.to" +class Sbnmp : Sbflix() { + override val name = "Sbnmp" + override var mainUrl = "https://sbnmp.bar" +} + class Sbrulz : Sbflix() { override val name = "Sbrulz" override var mainUrl = "https://sbrulz.xyz" diff --git a/Movierulzhd/src/main/kotlin/com/hexated/MovierulzhdPlugin.kt b/Movierulzhd/src/main/kotlin/com/hexated/MovierulzhdPlugin.kt index fb2bf567..21710b9d 100644 --- a/Movierulzhd/src/main/kotlin/com/hexated/MovierulzhdPlugin.kt +++ b/Movierulzhd/src/main/kotlin/com/hexated/MovierulzhdPlugin.kt @@ -13,5 +13,6 @@ class MovierulzhdPlugin: Plugin() { registerExtractorAPI(Sbflix()) registerExtractorAPI(Sbrulz()) registerExtractorAPI(Sbmiz()) + registerExtractorAPI(Sbnmp()) } } \ No newline at end of file From 69852f9e5b8e8b0a8cabecadbe847433233dad6c Mon Sep 17 00:00:00 2001 From: Suraj <29368267+geekboysuraj@users.noreply.github.com> Date: Thu, 13 Jul 2023 11:57:38 +0530 Subject: [PATCH 04/16] Updated movierulzhd URL (#176) * updated Movierulez URL * Updated movierulzHd URL * Update Movierulzhd URL --- Movierulzhd/build.gradle.kts | 2 +- Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Movierulzhd/build.gradle.kts b/Movierulzhd/build.gradle.kts index e25e9c0e..1d596ef2 100644 --- a/Movierulzhd/build.gradle.kts +++ b/Movierulzhd/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 36 +version = 37 cloudstream { diff --git a/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt b/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt index 26bc47d1..263375b7 100644 --- a/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt +++ b/Movierulzhd/src/main/kotlin/com/hexated/Movierulzhd.kt @@ -12,7 +12,7 @@ import org.jsoup.nodes.Element import java.net.URI class Movierulzhd : MainAPI() { - override var mainUrl = "https://movierulzhd.trade" + override var mainUrl = "https://movierulzhd.help" private var directUrl = mainUrl override var name = "Movierulzhd" override val hasMainPage = true From a4714873944996744da6d691bf88a5d89d570e84 Mon Sep 17 00:00:00 2001 From: tuan041 <30403510+tuan041@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:27:48 +0700 Subject: [PATCH 05/16] Fix Tocanime (#178) * bump * fix --- TocanimeProvider/build.gradle.kts | 6 +- .../kotlin/com/hexated/TocanimeProvider.kt | 60 ++++++------------- 2 files changed, 21 insertions(+), 45 deletions(-) diff --git a/TocanimeProvider/build.gradle.kts b/TocanimeProvider/build.gradle.kts index d7be42c7..dd3551a8 100644 --- a/TocanimeProvider/build.gradle.kts +++ b/TocanimeProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { @@ -7,7 +7,7 @@ cloudstream { // All of these properties are optional, you can safely remove them // description = "Lorem Ipsum" - authors = listOf("Hexated") + authors = listOf("Hexated, TuaSan") /** * Status int as the following: @@ -24,4 +24,4 @@ cloudstream { ) iconUrl = "https://www.google.com/s2/favicons?domain=tocanime.co&sz=%size%" -} \ No newline at end of file +} diff --git a/TocanimeProvider/src/main/kotlin/com/hexated/TocanimeProvider.kt b/TocanimeProvider/src/main/kotlin/com/hexated/TocanimeProvider.kt index 90a0f590..96728eda 100644 --- a/TocanimeProvider/src/main/kotlin/com/hexated/TocanimeProvider.kt +++ b/TocanimeProvider/src/main/kotlin/com/hexated/TocanimeProvider.kt @@ -29,14 +29,6 @@ class TocanimeProvider : MainAPI() { else -> TvType.Anime } } - - fun getStatus(t: String): ShowStatus { - return when (t) { - "Đã hoàn thành" -> ShowStatus.Completed - "Chưa hoàn thành" -> ShowStatus.Ongoing - else -> ShowStatus.Completed - } - } } override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { @@ -51,7 +43,6 @@ class TocanimeProvider : MainAPI() { } if (items.isNotEmpty()) homePageList.add(HomePageList(header, items)) } - return HomePageResponse(homePageList) } @@ -71,43 +62,38 @@ class TocanimeProvider : MainAPI() { this.posterUrl = posterUrl addSub(epNum) } - } override suspend fun search(query: String): List { val document = app.get("$mainUrl/content/search?t=kw&q=$query").document - return document.select("div.col-lg-3.col-md-4.col-6").map { it.toSearchResult() } - } override suspend fun load(url: String): LoadResponse? { val document = app.get(url).document val title = document.selectFirst("h1.title")?.text() ?: return null - val type = - if (document.select("div.me-list.scroller a").size == 1) TvType.AnimeMovie else TvType.Anime - val episodes = document.select("div.me-list.scroller a").mapNotNull { - Episode(fixUrl(it.attr("href")), it.text()) - }.reversed() + val poster = fixUrlNull(document.selectFirst("img.mb20")?.attr("data-original")) val trailer = document.selectFirst("div#trailer script")?.data()?.substringAfter("