From c26af343ac306ec769c358663631525ac0ec307e Mon Sep 17 00:00:00 2001 From: hexated Date: Sun, 17 Sep 2023 07:31:27 +0700 Subject: [PATCH] close #278 --- .../src/main/kotlin/com/hexated/Aniworld.kt | 73 ++++--------------- .../main/kotlin/com/hexated/AniworldPlugin.kt | 2 - IdlixProvider/build.gradle.kts | 2 +- .../main/kotlin/com/hexated/IdlixProvider.kt | 61 +++++++++++++++- 4 files changed, 76 insertions(+), 62 deletions(-) diff --git a/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt b/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt index f55ac59e..1fb28346 100644 --- a/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt +++ b/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt @@ -7,11 +7,9 @@ import com.lagradost.cloudstream3.extractors.DoodLaExtractor import com.lagradost.cloudstream3.extractors.Voe import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.M3u8Helper import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import java.net.URI open class Aniworld : MainAPI() { override var mainUrl = "https://aniworld.to" @@ -25,24 +23,6 @@ open class Aniworld : MainAPI() { TvType.OVA ) - companion object { - fun getType(t: String): TvType { - return when { - t.contains("Anime Ova") -> TvType.OVA - t.contains("Anime Movie") -> TvType.AnimeMovie - else -> TvType.Anime - } - } - - fun getStatus(t: String): ShowStatus { - return when { - t.contains("/complete", true) -> ShowStatus.Completed - t.contains("/running", true) -> ShowStatus.Ongoing - else -> ShowStatus.Completed - } - } - } - override suspend fun getMainPage( page: Int, request: MainPageRequest @@ -146,11 +126,24 @@ open class Aniworld : MainAPI() { }.apmap { val redirectUrl = app.get(fixUrl(it.second)).url val lang = it.first.getLanguage(document) + val name = "${it.third} [${lang}]" if (it.third == "VOE") { - invokeVoe(redirectUrl, lang, data, callback) + Voe().getUrl(redirectUrl, data, subtitleCallback) { link -> + callback.invoke( + ExtractorLink( + name, + name, + link.url, + link.referer, + link.quality, + link.type, + link.headers, + link.extractorData + ) + ) + } } else { loadExtractor(redirectUrl, data, subtitleCallback) { link -> - val name = "${link.name} [${lang}]" callback.invoke( ExtractorLink( name, @@ -170,28 +163,6 @@ open class Aniworld : MainAPI() { return true } - private suspend fun invokeVoe( - url: String, - lang: String?, - referer: String, - callback: (ExtractorLink) -> Unit, - ) { - val name = "Voe [${lang}]" - val request = app.get(url, referer = referer) - val baseUrl = getBaseUrl(request.url) - val res = request.document - val script = res.select("script").find { it.data().contains("sources =") }?.data() - val link = - Regex("[\"']hls[\"']:\\s*[\"'](.*)[\"']").find(script ?: return)?.groupValues?.get(1) - - M3u8Helper.generateM3u8( - name, - link ?: return, - "$baseUrl/", - headers = mapOf("Origin" to "$baseUrl/") - ).forEach(callback) - } - private fun Element.toSearchResult(): AnimeSearchResponse? { val href = fixUrlNull(this.selectFirst("a")?.attr("href")) ?: return null val title = this.selectFirst("h3")?.text() ?: return null @@ -206,12 +177,6 @@ open class Aniworld : MainAPI() { ?.removePrefix("mit")?.trim() } - private fun getBaseUrl(url: String): String { - return URI(url).let { - "${it.scheme}://${it.host}" - } - } - private data class AnimeSearch( @JsonProperty("link") val link: String, @JsonProperty("title") val title: String? = null, @@ -221,12 +186,4 @@ open class Aniworld : MainAPI() { class Dooood : DoodLaExtractor() { override var mainUrl = "https://urochsunloath.com" -} - -class Simpulumlamerop : Voe() { - override var mainUrl = "https://simpulumlamerop.com" -} - -class Urochsunloath : Voe() { - override var mainUrl = "https://urochsunloath.com" } \ No newline at end of file diff --git a/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt b/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt index 7eee506e..3e86596b 100644 --- a/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt +++ b/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt @@ -11,8 +11,6 @@ class AniworldPlugin: Plugin() { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(Aniworld()) registerMainAPI(Serienstream()) - registerExtractorAPI(Urochsunloath()) - registerExtractorAPI(Simpulumlamerop()) registerExtractorAPI(Dooood()) } } \ No newline at end of file diff --git a/IdlixProvider/build.gradle.kts b/IdlixProvider/build.gradle.kts index f7ae78c8..9a92e993 100644 --- a/IdlixProvider/build.gradle.kts +++ b/IdlixProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 16 +version = 17 cloudstream { diff --git a/IdlixProvider/src/main/kotlin/com/hexated/IdlixProvider.kt b/IdlixProvider/src/main/kotlin/com/hexated/IdlixProvider.kt index 76bb017c..aa2f9c76 100644 --- a/IdlixProvider/src/main/kotlin/com/hexated/IdlixProvider.kt +++ b/IdlixProvider/src/main/kotlin/com/hexated/IdlixProvider.kt @@ -211,7 +211,7 @@ class IdlixProvider : MainAPI() { val decrypted = AesHelper.cryptoAESHandler(json.embed_url, password.toByteArray(), false)?.fixBloat() ?: return@apmap when { - !decrypted.contains("youtube") -> loadExtractor(decrypted, "$directUrl/", subtitleCallback, callback) + !decrypted.contains("youtube") -> getUrl(decrypted, "$directUrl/", subtitleCallback, callback) else -> return@apmap } } @@ -233,6 +233,65 @@ class IdlixProvider : MainAPI() { return this.replace("\"", "").replace("\\", "") } + private suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val document = app.get(url, referer = referer).document + val hash = url.split("/").last().substringAfter("data=") + + val m3uLink = app.post( + url = "https://jeniusplay.com/player/index.php?data=$hash&do=getVideo", + data = mapOf("hash" to hash, "r" to "$referer"), + referer = referer, + headers = mapOf("X-Requested-With" to "XMLHttpRequest") + ).parsed().videoSource + + M3u8Helper.generateM3u8( + this.name, + m3uLink, + "$referer", + ).forEach(callback) + + + document.select("script").map { script -> + if (script.data().contains("eval(function(p,a,c,k,e,d)")) { + val subData = + getAndUnpack(script.data()).substringAfter("\"tracks\":[").substringBefore("],") + AppUtils.tryParseJson>("[$subData]")?.map { subtitle -> + subtitleCallback.invoke( + SubtitleFile( + getLanguage(subtitle.label ?: ""), + subtitle.file + ) + ) + } + } + } + } + + private fun getLanguage(str: String): String { + return when { + str.contains("indonesia", true) || str + .contains("bahasa", true) -> "Indonesian" + else -> str + } + } + + data class ResponseSource( + @JsonProperty("hls") val hls: Boolean, + @JsonProperty("videoSource") val videoSource: String, + @JsonProperty("securedLink") val securedLink: String?, + ) + + data class Tracks( + @JsonProperty("kind") val kind: String?, + @JsonProperty("file") val file: String, + @JsonProperty("label") val label: String?, + ) + data class ResponseHash( @JsonProperty("embed_url") val embed_url: String, @JsonProperty("key") val key: String,