From cecf322fad5136aed4f9af6b388f66aee5255c0b Mon Sep 17 00:00:00 2001 From: hexated Date: Fri, 16 Jun 2023 06:38:22 +0700 Subject: [PATCH] sora: fix Vidcloud & Upcloud --- SoraStream/build.gradle.kts | 2 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 143 ++++++++++-------- .../src/main/kotlin/com/hexated/SoraStream.kt | 18 +-- .../main/kotlin/com/hexated/SoraStreamLite.kt | 13 +- 4 files changed, 88 insertions(+), 88 deletions(-) diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index bfb58419..9ec53722 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 = 137 +version = 138 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 6b4c27aa..3a5a0e64 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -15,50 +15,91 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody import okio.ByteString.Companion.encode import org.jsoup.Jsoup +import org.jsoup.nodes.Document val session = Session(Requests().baseClient) object SoraExtractor : SoraStream() { - suspend fun invokeTwoEmbed( - id: Int? = null, + suspend fun invokeGoku( + title: String? = null, + year: Int? = null, season: Int? = null, + lastSeason: Int? = null, episode: Int? = null, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ) { - val url = if (season == null) { - "$twoEmbedAPI/embed/tmdb/movie?id=$id" - } else { - "$twoEmbedAPI/embed/tmdb/tv?id=$id&s=$season&e=$episode" - } - val document = app.get(url).document - val captchaKey = - document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]") - .attr("src").substringAfter("render=") + val headers = mapOf( + "X-Requested-With" to "XMLHttpRequest" + ) - document.select(".dropdown-menu a[data-id]").map { it.attr("data-id") }.apmap { serverID -> - val token = APIHolder.getCaptchaToken(url, captchaKey) + fun Document.getServers(): List { + return this.select("a").map { it.attr("data-id") } + } + + val media = app.get( + "$gokuAPI/ajax/movie/search?keyword=$title", headers = headers + ).document.select("div.item").find { ele -> + val url = ele.selectFirst("a")?.attr("href") + val titleMedia = ele.select("h3.movie-name").text() + val yearMedia = + ele.selectFirst("div.info-split > div:first-child")?.text()?.toIntOrNull() + val lastSeasonMedia = + ele.selectFirst("div.info-split > div:nth-child(2)")?.text()?.substringAfter("SS") + ?.substringBefore("/")?.toIntOrNull() + titleMedia.equals(title, true) || titleMedia.createSlug().equals(title.createSlug()) && + if (season == null) { + yearMedia == year && url?.contains("/series/") == true + } else { + lastSeasonMedia == lastSeason && url?.contains("/movie/") == true + } + } ?: return + + val serversId = if (season == null) { + val movieId = app.get( + fixUrl( + media.selectFirst("a")?.attr("href") ?: return, + gokuAPI + ) + ).url.substringAfterLast("/") app.get( - "$twoEmbedAPI/ajax/embed/play?id=$serverID&_token=$token", referer = url - ).parsedSafe()?.let { source -> - val link = source.link ?: return@let - if (link.contains("rabbitstream")) { - extractRabbitStream( - "Vidcloud", - link, - "$twoEmbedAPI/", - subtitleCallback, - callback, - false, - decryptKey = RabbitStream.getKey() - ) { it } - } else { - loadExtractor( - link, twoEmbedAPI, subtitleCallback, callback - ) - } - } + "$gokuAPI/ajax/movie/episode/servers/$movieId", + headers = headers + ).document.getServers() + } else { + val seasonId = app.get( + "$gokuAPI/ajax/movie/seasons/${ + media.selectFirst("a.btn-wl")?.attr("data-id") ?: return + }", headers = headers + ).document.select("a.ss-item").find { it.ownText().equals("Season $season", true) }?.attr("data-id") + val episodeId = + app.get( + "$gokuAPI/ajax/movie/season/episodes/${seasonId ?: return}", + headers = headers + ).document.select("div.item").find { + it.selectFirst("strong")?.text().equals("Eps $episode:", true) + }?.selectFirst("a")?.attr("data-id") + + app.get( + "$gokuAPI/ajax/movie/episode/servers/${episodeId ?: return}", + headers = headers + ).document.getServers() + } + + serversId.apmap { id -> + val iframe = + app.get("$gokuAPI/ajax/movie/episode/server/sources/$id", headers = headers) + .parsedSafe()?.data?.link ?: return@apmap + extractRabbitStream( + if (iframe.contains("rabbitstream")) "Vidcloud" else "Upcloud", + iframe, + "$gokuAPI/", + subtitleCallback, + callback, + false, + decryptKey = RabbitStream.getKey() + ) { it } } } @@ -2905,36 +2946,6 @@ object SoraExtractor : SoraStream() { } - suspend fun invokeUpcloud( - imdbId: String? = null, - season: Int? = null, - episode: Int? = null, - callback: (ExtractorLink) -> Unit - ) { - val apiUrl = - base64DecodeAPI("dWI=Y2w=cC4=bXU=ZWE=LWI=Ynk=YmE=bS4=ZWE=dHI=ZXM=aW4=LWM=NDA=MDg=NjE=YmQ=Y2I=MmU=Ly8=czo=dHA=aHQ=") - val url = if (season == null) { - "$apiUrl/stream/movie/$imdbId.json" - } else { - "$apiUrl/stream/series/$imdbId:$season:$episode.json" - } - - app.get(url).parsedSafe()?.streams?.map { stream -> - callback.invoke( - ExtractorLink( - "Upcloud", - "Upcloud", - stream.url ?: return@map, - "", - stream.description?.toIntOrNull() ?: Qualities.Unknown.value, - headers = stream.behaviorHints?.proxyHeaders?.request ?: mapOf(), - isM3u8 = true - ) - ) - } - - } - suspend fun invokeNowTv( tmdbId: Int? = null, callback: (ExtractorLink) -> Unit @@ -3400,4 +3411,12 @@ data class ZoroResponses( data class MalSyncRes( @JsonProperty("Sites") val Sites: Map>>? = null, +) + +data class GokuData( + @JsonProperty("link") val link: String? = null, +) + +data class GokuServer( + @JsonProperty("data") val data: GokuData? = GokuData(), ) \ No newline at end of file diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 6a601cde..e240952a 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -15,7 +15,6 @@ import com.hexated.SoraExtractor.invokeKimcartoon import com.hexated.SoraExtractor.invokeMovieHab import com.hexated.SoraExtractor.invokeNoverse import com.hexated.SoraExtractor.invokeSeries9 -import com.hexated.SoraExtractor.invokeTwoEmbed import com.hexated.SoraExtractor.invokeVidSrc import com.hexated.SoraExtractor.invokeXmovies import com.lagradost.cloudstream3.* @@ -30,6 +29,7 @@ import com.hexated.SoraExtractor.invokeFmovies import com.hexated.SoraExtractor.invokeFwatayako import com.hexated.SoraExtractor.invokeGMovies import com.hexated.SoraExtractor.invokeGdbotMovies +import com.hexated.SoraExtractor.invokeGoku import com.hexated.SoraExtractor.invokeGomovies import com.hexated.SoraExtractor.invokeJmdkhMovies import com.hexated.SoraExtractor.invokeKisskh @@ -50,7 +50,6 @@ import com.hexated.SoraExtractor.invokeSmashyStream import com.hexated.SoraExtractor.invokeSoraStream import com.hexated.SoraExtractor.invokeTvMovies import com.hexated.SoraExtractor.invokeUhdmovies -import com.hexated.SoraExtractor.invokeUpcloud import com.hexated.SoraExtractor.invokeVitoenMovies import com.hexated.SoraExtractor.invokeWatchOnline import com.hexated.SoraExtractor.invokeWatchsomuch @@ -85,7 +84,6 @@ open class SoraStream : TmdbProvider() { base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL /** ALL SOURCES */ - const val twoEmbedAPI = "https://www.2embed.to" const val vidSrcAPI = "https://v2.vidsrc.me" const val dbgoAPI = "https://dbgo.fun" const val movieHabAPI = "https://moviehab.com" @@ -117,8 +115,7 @@ open class SoraStream : TmdbProvider() { const val movie123NetAPI = "https://ww8.0123movie.net" 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=") + 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 watchOnlineAPI = "https://watchonline.ag" @@ -126,6 +123,7 @@ open class SoraStream : TmdbProvider() { const val putlockerAPI = "https://ww7.putlocker.vip" const val fmoviesAPI = "https://fmovies.to" const val nowTvAPI = "https://myfilestorage.xyz" + const val gokuAPI = "https://goku.sx" // INDEX SITE const val blackMoviesAPI = "https://dl.blacklistedbois.workers.dev/0:" @@ -388,7 +386,7 @@ open class SoraStream : TmdbProvider() { ) }, { - invokeTwoEmbed(res.id, res.season, res.episode, subtitleCallback, callback) + invokeGoku(res.title, res.year, res.season, res.lastSeason, res.episode, subtitleCallback, callback) }, { invokeVidSrc(res.id, res.season, res.episode, subtitleCallback, callback) @@ -566,14 +564,6 @@ open class SoraStream : TmdbProvider() { callback ) }, - { - if (!res.isAnime) invokeUpcloud( - res.imdbId, - res.season, - res.episode, - callback - ) - }, { invokePutlocker(res.title, res.year, res.season, res.episode, callback) }, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index d038c3be..450c4d1c 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -8,6 +8,7 @@ import com.hexated.SoraExtractor.invokeFilmxy import com.hexated.SoraExtractor.invokeFlixon import com.hexated.SoraExtractor.invokeFmovies import com.hexated.SoraExtractor.invokeFwatayako +import com.hexated.SoraExtractor.invokeGoku import com.hexated.SoraExtractor.invokeGomovies import com.hexated.SoraExtractor.invokeHDMovieBox import com.hexated.SoraExtractor.invokeIdlix @@ -24,8 +25,6 @@ import com.hexated.SoraExtractor.invokeRStream import com.hexated.SoraExtractor.invokeSeries9 import com.hexated.SoraExtractor.invokeSmashyStream import com.hexated.SoraExtractor.invokeSoraStream -import com.hexated.SoraExtractor.invokeTwoEmbed -import com.hexated.SoraExtractor.invokeUpcloud import com.hexated.SoraExtractor.invokeVidSrc import com.hexated.SoraExtractor.invokeWatchOnline import com.hexated.SoraExtractor.invokeWatchsomuch @@ -85,7 +84,7 @@ class SoraStreamLite : SoraStream() { ) }, { - invokeTwoEmbed(res.id, res.season, res.episode, subtitleCallback, callback) + invokeGoku(res.title, res.year, res.season, res.lastSeason, res.episode, subtitleCallback, callback) }, { invokeVidSrc(res.id, res.season, res.episode, subtitleCallback, callback) @@ -197,14 +196,6 @@ class SoraStreamLite : SoraStream() { callback ) }, - { - if (!res.isAnime) invokeUpcloud( - res.imdbId, - res.season, - res.episode, - callback - ) - }, { invokeXmovies( res.title,