diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 55a24678..04e1985b 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 100 +version = 101 cloudstream { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index a4961acc..763f793f 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -1157,7 +1157,6 @@ object SoraExtractor : SoraStream() { season: Int? = null, lastSeason: Int? = null, episode: Int? = null, - epsTitle: String? = null, callback: (ExtractorLink) -> Unit ) { val slug = title.createSlug()?.replace("-", " ") @@ -1184,7 +1183,7 @@ object SoraExtractor : SoraStream() { it.text() to it.nextElementSibling()?.select("a")?.attr("href") } else { it.text() to it.nextElementSibling() - ?.select("a:matches((Episode $episode)|($epsTitle))") + ?.select("a")?.find { child -> child.select("span").text().equals("Episode $episode", true) } ?.attr("href") } }.filter { it.second?.contains(Regex("(https:)|(http:)")) == true } @@ -1215,10 +1214,7 @@ object SoraExtractor : SoraStream() { sources.apmap { (quality, link) -> val driveLink = bypassHrefli(link ?: return@apmap null) val base = getBaseUrl(driveLink ?: return@apmap null) - val resDoc = app.get(driveLink).text.substringAfter("replace(\"") - .substringBefore("\")").let { - app.get(fixUrl(it, base)).document - } + val resDoc = app.get(driveLink).document val bitLink = resDoc.selectFirst("a.btn.btn-outline-success")?.attr("href") val downloadLink = if (bitLink.isNullOrEmpty()) { val backupIframe = resDoc.select("a.btn.btn-outline-warning").attr("href") diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 60fe4ee4..7dde7063 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -97,7 +97,7 @@ open class SoraStream : TmdbProvider() { const val filmxyAPI = "https://www.filmxy.vip" const val kimcartoonAPI = "https://kimcartoon.li" const val xMovieAPI = "https://xemovies.to" - const val haikeiFlixhqAPI = "https://api.haikei.xyz/movies/flixhq" // disabled + const val haikeiFlixhqAPI = "https://api.haikei.xyz/movies/flixhq" // disabled due to rate limit const val consumetZoroAPI = "https://api.consumet.org/anime/zoro" const val consumetCrunchyrollAPI = "https://cronchy.consumet.stream" const val kickassanimeAPI = "https://www2.kickassanime.ro" // disabled due to consumet @@ -503,7 +503,6 @@ open class SoraStream : TmdbProvider() { res.season, res.lastSeason, res.episode, - res.epsTitle, callback ) }, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index 9972e28c..6c16ff3e 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -158,17 +158,11 @@ suspend fun extractMirrorUHD(url: String, ref: String): String? { downLink = baseDoc.getMirrorLink() } } - if (downLink?.contains(".mkv") == true || downLink?.contains(".mp4") == true) return downLink - val downPage = app.get(downLink ?: return null).document - return downPage.selectFirst("form[method=post] a.btn.btn-success") - ?.attr("onclick")?.substringAfter("Openblank('")?.substringBefore("')") ?: run { - val mirror = downPage.selectFirst("form[method=post] a.btn.btn-primary") - ?.attr("onclick")?.substringAfter("Openblank('")?.substringBefore("')") - app.get( - mirror ?: return null - ).document.selectFirst("script:containsData(input.value =)") - ?.data()?.substringAfter("input.value = '")?.substringBefore("';") - } + return if (downLink?.contains("workers.dev") == true) downLink else base64Decode( + downLink?.substringAfter( + "download?url=" + ) ?: return null + ) } suspend fun extractBackupUHD(url: String): String? { @@ -619,31 +613,34 @@ suspend fun bypassFdAds(url: String?): String? { } suspend fun bypassHrefli(url: String): String? { - var res = app.get(url.removePrefix("https://href.li/?")) - (1..2).forEach { _ -> - val document = res.document - val nextUrl = document.select("form").attr("action") - val data = document.select("form input").mapNotNull { - it.attr("name") to it.attr("value") - }.toMap() - res = app.post( - nextUrl, - data = data, + val postUrl = url.substringBefore("?id=").substringAfter("/?") + val res = app.post( + postUrl, data = mapOf( + "_wp_http" to url.substringAfter("?id=") ) - } - val script = res.document.selectFirst("script:containsData(verify_button)")?.data() - val goUrl = script?.substringAfter("\"href\",\"")?.substringBefore("\")") - val cookies = - Regex("sumitbot_\\('(\\S+?)',\n|.?'(\\S+?)',").findAll(script ?: return null).map { - it.groupValues[2] - }.toList().let { - mapOf(it.first() to it.last()) - }.ifEmpty { return null } + ).document - return app.get( - goUrl ?: return null, - cookies = cookies + val link = res.select("form#landing").attr("action") + val wpHttp = res.select("input[name=_wp_http2]").attr("value") + val token = res.select("input[name=token]").attr("value") + + val blogRes = app.post( + link, data = mapOf( + "_wp_http2" to wpHttp, + "token" to token + ) + ).text + + val skToken = blogRes.substringAfter("?go=").substringBefore("\"") + val driveUrl = app.get( + "$postUrl?go=$skToken", cookies = mapOf( + skToken to wpHttp + ) ).document.selectFirst("meta[http-equiv=refresh]")?.attr("content")?.substringAfter("url=") + val path = app.get(driveUrl ?: return null).text.substringAfter("replace(\"") + .substringBefore("\")") + if (path == "/404") return null + return fixUrl(path, getBaseUrl(driveUrl)) } suspend fun getTvMoviesServer(url: String, season: Int?, episode: Int?): Pair? {