From 2a55a256aa526ec304a51fa7fd7a6318dd7dc194 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Sun, 12 Dec 2021 02:49:41 +0100 Subject: [PATCH] massively improved zoro --- .../animeproviders/ZoroProvider.kt | 95 ++++++++++--------- .../cloudstream3/extractors/WatchSB.kt | 45 +++++++++ .../cloudstream3/network/Requests.kt | 3 + .../cloudstream3/ui/player/PlayerFragment.kt | 6 +- .../cloudstream3/utils/ExtractorApi.kt | 9 +- 5 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt index dd6a4a32..e441c366 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt @@ -8,6 +8,7 @@ import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toExtra import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile import com.lagradost.cloudstream3.network.WebViewResolver import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup import org.jsoup.nodes.Element import java.net.URI @@ -152,7 +153,8 @@ class ZoroProvider : MainAPI() { EnumSet.of(DubStatus.Subbed) } - val tvType = getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString()) + val tvType = + getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString()) val href = fixUrl(it.selectFirst(".film-name a").attr("href")) AnimeSearchResponse( @@ -187,7 +189,8 @@ class ZoroProvider : MainAPI() { when { (year != null && japaneseTitle != null && status != null) -> break text.contains("Premiered") && year == null -> - year = info.selectFirst(".name")?.text().toString().split(" ").last().toIntOrNull() + year = + info.selectFirst(".name")?.text().toString().split(" ").last().toIntOrNull() text.contains("Japanese") && japaneseTitle == null -> japaneseTitle = info.selectFirst(".name")?.text().toString() @@ -255,61 +258,59 @@ class ZoroProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { - // Copy pasted from Sflix :) - val servers: List> = Jsoup.parse( - mapper.readValue( - app.get("$mainUrl/ajax/v2/episode/servers?episodeId=" + data.split("=")[1]).text - ).html + app.get("$mainUrl/ajax/v2/episode/servers?episodeId=" + data.split("=")[1]) + .mapped().html ).select(".server-item[data-type][data-id]").map { - Pair(if (it.attr("data-type") == "sub") DubStatus.Subbed else DubStatus.Dubbed, it.attr("data-id")!!) - } - - val res = app.get( - data, - interceptor = WebViewResolver( - Regex("""/getSources""") - ) - ) -// println("RES TEXT ${res.text}") - - val recaptchaToken = res.response.request.url.queryParameter("_token") - - val responses = servers.map { - val link = "$mainUrl/ajax/v2/episode/sources?id=${it.second}&_token=$recaptchaToken" Pair( - it.first, - getM3u8FromRapidCloud( - mapper.readValue( - app.get( - link, - res.headers.toMap() - ).text - ).link - ) + if (it.attr("data-type") == "sub") DubStatus.Subbed else DubStatus.Dubbed, + it.attr("data-id")!! ) } - responses.forEach { - if (it.second.contains("(it.second) + // Prevent duplicates + servers.distinctBy { it.second }.pmap { + val link = + "$mainUrl/ajax/v2/episode/sources?id=${it.second}" + val extractorLink = app.get( + link, + ).mapped().link - mapped.tracks?.forEach { track -> - track?.toSubtitleFile()?.let { subtitleFile -> - subtitleCallback.invoke(subtitleFile) + // Loads the links in the appropriate extractor. + val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback) + + if (!hasLoadedExtractorLink) { + + // Not an extractor because: + // 1. No subtitle callback + // 2. Missing dub/sub status in parameter (might be substituted in the referer) + + val response = + getM3u8FromRapidCloud( + extractorLink + ) + + if (response.contains("(response) + + mapped.tracks?.forEach { track -> + track?.toSubtitleFile()?.let { subtitleFile -> + subtitleCallback.invoke(subtitleFile) + } } - } - val list = listOf( - mapped.sources to "source 1", - mapped.sources1 to "source 2", - mapped.sources2 to "source 3", - mapped.sourcesBackup to "source backup" - ) + val list = listOf( + mapped.sources to "source 1", + mapped.sources1 to "source 2", + mapped.sources2 to "source 3", + mapped.sourcesBackup to "source backup" + ) - list.forEach { subList -> - subList.first?.forEach { a -> - a?.toExtractorLink(this, subList.second + " - ${it.first}")?.forEach(callback) + list.forEach { subList -> + subList.first?.forEach { a -> + a?.toExtractorLink(this, subList.second + " - ${it.first}") + ?.forEach(callback) + } } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt new file mode 100644 index 00000000..6602e27c --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt @@ -0,0 +1,45 @@ +package com.lagradost.cloudstream3.extractors + +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.network.WebViewResolver +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.M3u8Helper +import com.lagradost.cloudstream3.utils.getQualityFromName + +class WatchSB : ExtractorApi() { + override val name: String + get() = "WatchSB" + override val mainUrl: String + get() = "https://watchsb.com" + override val requiresReferer: Boolean + get() = false + + override fun getUrl(url: String, referer: String?): List { + val response = app.get( + url, interceptor = WebViewResolver( + Regex("""master\.m3u8""") + ) + ) + + val extractedLinksList = M3u8Helper().m3u8Generation( + M3u8Helper.M3u8Stream( + response.url, + headers = response.headers.toMap() + ), true + ) + .map { stream -> + val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p" + ExtractorLink( + name, + "$name $qualityString", + stream.streamUrl, + url, + getQualityFromName(stream.quality.toString()), + true + ) + } + + return extractedLinksList + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt index 20f90f77..c0e20588 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt @@ -9,6 +9,8 @@ import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.mapper import okhttp3.* import okhttp3.Headers.Companion.toHeaders +import org.jsoup.Jsoup +import org.jsoup.nodes.Document import java.io.File import java.net.URI import java.util.* @@ -78,6 +80,7 @@ class AppResponse( val body by lazy { response.body } val code = response.code val headers = response.headers + val document: Document by lazy { Jsoup.parse(text) } /** Same as using mapper.readValue() */ inline fun mapped(): T { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt index c2d885e7..996fdf44 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt @@ -741,9 +741,7 @@ class PlayerFragment : Fragment() { } private fun safeReleasePlayer() { - thread { - simpleCache?.release() - } + simpleCache?.release() if (this::exoPlayer.isInitialized) { exoPlayer.release() } @@ -1928,7 +1926,6 @@ class PlayerFragment : Fragment() { // torrentStream?.stopStream() // torrentStream = null - super.onDestroy() canEnterPipMode = false savePositionInPlayer() @@ -1938,6 +1935,7 @@ class PlayerFragment : Fragment() { activity?.showSystemUI() activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER + super.onDestroy() } override fun onPause() { diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 98642c50..592bc066 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -58,13 +58,17 @@ fun getAndUnpack(string: String): String { return JsUnpacker(packedText).unpack() ?: string } -fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) { +/** + * Tries to load the appropriate extractor based on link, returns true if any extractor is loaded. + * */ +fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) : Boolean { for (extractor in extractorApis) { if (url.startsWith(extractor.mainUrl)) { extractor.getSafeUrl(url, referer)?.forEach(callback) - return + return true } } + return false } val extractorApis: Array = arrayOf( @@ -78,6 +82,7 @@ val extractorApis: Array = arrayOf( Streamhub(), SBPlay(), FEmbed(), + WatchSB(), // dood extractors DoodToExtractor(),