From 8555791960c56c11bd070f570dbaecdd18e7947c Mon Sep 17 00:00:00 2001 From: Samfun75 <38332931+Samfun75@users.noreply.github.com> Date: Wed, 12 Apr 2023 22:09:52 +0300 Subject: [PATCH] UHDMovies: Re add the redirect shenanigan (#1483) --- src/en/uhdmovies/build.gradle | 2 +- .../animeextension/en/uhdmovies/UHDMovies.kt | 61 ++++++++++++++++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/en/uhdmovies/build.gradle b/src/en/uhdmovies/build.gradle index a46171a5e..0ab6907b3 100644 --- a/src/en/uhdmovies/build.gradle +++ b/src/en/uhdmovies/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'UHD Movies' pkgNameSuffix = 'en.uhdmovies' extClass = '.UHDMovies' - extVersionCode = 12 + extVersionCode = 13 libVersion = '13' } diff --git a/src/en/uhdmovies/src/eu/kanade/tachiyomi/animeextension/en/uhdmovies/UHDMovies.kt b/src/en/uhdmovies/src/eu/kanade/tachiyomi/animeextension/en/uhdmovies/UHDMovies.kt index f9d1d5b1a..8b42be669 100644 --- a/src/en/uhdmovies/src/eu/kanade/tachiyomi/animeextension/en/uhdmovies/UHDMovies.kt +++ b/src/en/uhdmovies/src/eu/kanade/tachiyomi/animeextension/en/uhdmovies/UHDMovies.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.util.asJsoup import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -23,8 +24,11 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import okhttp3.FormBody +import okhttp3.Headers import okhttp3.OkHttpClient import okhttp3.Request +import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable @@ -129,7 +133,7 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() { override fun fetchEpisodeList(anime: SAnime): Observable> { val resp = client.newCall(GET(currentBaseUrl + anime.url)).execute().asJsoup() val episodeList = mutableListOf() - val episodeElements = resp.select("p:has(a[href*=r?key=]):has(a[class*=maxbutton])[style*=center]") + val episodeElements = resp.select("p:has(a[href*=?id=],a[href*=r?key=]):has(a[class*=maxbutton])[style*=center]") val qualityRegex = "\\d{3,4}p".toRegex(RegexOption.IGNORE_CASE) val firstText = episodeElements.first()!!.text() if (firstText.contains("Episode", true) || @@ -288,7 +292,36 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() { // ============================= Utilities ============================== private fun extractVideo(epUrl: EpUrl): Pair, String> { - val mediaResponse = client.newCall(GET(epUrl.url)).execute() + val mediaResponse = if (epUrl.url.contains("?id=")) { + val postLink = epUrl.url.substringBefore("?id=").substringAfter("/?") + val formData = FormBody.Builder().add("_wp_http_c", epUrl.url.substringAfter("?id=")).build() + val response = client.newCall(POST(postLink, body = formData)).execute().body.string() + val (longC, catC, _) = getCookiesDetail(response) + val cookieHeader = Headers.headersOf("Cookie", "$longC; $catC") + val parsedSoup = Jsoup.parse(response) + val link = parsedSoup.selectFirst("center > a")!!.attr("href") + + val response2 = client.newCall(GET(link, cookieHeader)).execute().body.string() + val (longC2, _, postC) = getCookiesDetail(response2) + val cookieHeader2 = Headers.headersOf("Cookie", "$catC; $longC2; $postC") + val parsedSoup2 = Jsoup.parse(response2) + val link2 = parsedSoup2.selectFirst("center > a")!!.attr("href") + + val tokenResp = client.newCall(GET(link2, cookieHeader2)).execute().body.string() + val goToken = tokenResp.substringAfter("?go=").substringBefore("\"") + val tokenUrl = "$postLink?go=$goToken" + val newLongC = "$goToken=" + longC2.substringAfter("=") + val tokenCookie = Headers.headersOf("Cookie", "$catC; rdst_post=; $newLongC") + + val noRedirectClient = client.newBuilder().followRedirects(false).build() + val tokenResponse = noRedirectClient.newCall(GET(tokenUrl, tokenCookie)).execute().asJsoup() + val redirectUrl = tokenResponse.select("meta[http-equiv=refresh]").attr("content") + .substringAfter("url=").substringBefore("\"") + noRedirectClient.newCall(GET(redirectUrl)).execute() + } else if (epUrl.url.contains("r?key=")) { + client.newCall(GET(epUrl.url)).execute() + } else { throw Exception("Something went wrong") } + val path = mediaResponse.body.string().substringAfter("replace(\"").substringBefore("\"") if (path == "/404") return Pair(emptyList(), "") val mediaUrl = "https://" + mediaResponse.request.url.host + path @@ -302,6 +335,30 @@ class UHDMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() { return Pair(videoList, mediaUrl) } + private fun getCookiesDetail(page: String): Triple { + val cat = "rdst_cat" + val post = "rdst_post" + val longC = page.substringAfter(".setTime") + .substringAfter("document.cookie = \"") + .substringBefore("\"") + .substringBefore(";") + val catC = if (page.contains("$cat=")) { + page.substringAfterLast("$cat=") + .substringBefore(";").let { + "$cat=$it" + } + } else { "" } + + val postC = if (page.contains("$post=")) { + page.substringAfterLast("$post=") + .substringBefore(";").let { + "$post=$it" + } + } else { "" } + + return Triple(longC, catC, postC) + } + private val sizeRegex = "\\[((?:.(?!\\[))+)] *\$".toRegex(RegexOption.IGNORE_CASE) private fun extractWorkerLinks(mediaUrl: String, quality: String, type: Int): List