sora: fix upcloud,vidcloud, aniwatch

This commit is contained in:
hexated 2023-07-24 01:05:02 +07:00
parent 39d5247101
commit f38a602b97
5 changed files with 38 additions and 27 deletions

View File

@ -1,7 +1,7 @@
import org.jetbrains.kotlin.konan.properties.Properties
// use an integer for version numbers
version = 145
version = 146
android {
defaultConfig {

View File

@ -930,7 +930,7 @@ object SoraExtractor : SoraStream() {
argamap(
{
invokeZoro(aniId, episode, subtitleCallback, callback)
invokeAniwatch(malId, episode, subtitleCallback, callback)
},
{
invokeAnimeKaizoku(malId, epsTitle, season, episode, callback)
@ -1004,28 +1004,26 @@ object SoraExtractor : SoraStream() {
}
private suspend fun invokeZoro(
aniId: Int? = null,
private suspend fun invokeAniwatch(
malId: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val animeId =
app.get("https://raw.githubusercontent.com/MALSync/MAL-Sync-Backup/master/data/anilist/anime/${aniId ?: return}.json")
.parsedSafe<MALSyncResponses>()?.pages?.zoro?.keys?.map { it }
val headers = mapOf(
"X-Requested-With" to "XMLHttpRequest",
)
val animeId = app.get("$malsyncAPI/mal/anime/${malId ?: return}").parsedSafe<MALSyncResponses>()?.sites?.zoro?.keys?.map { it }
animeId?.apmap { id ->
val episodeId = app.get("$zoroAPI/ajax/episode/list/${id ?: return@apmap}", headers = headers)
.parsedSafe<ZoroResponses>()?.html?.let {
val episodeId = app.get("$aniwatchAPI/ajax/v2/episode/list/${id ?: return@apmap}", headers = headers)
.parsedSafe<AniwatchResponses>()?.html?.let {
Jsoup.parse(it)
}?.select("div.ss-list a")?.find { it.attr("data-number") == "${episode ?: 1}" }
?.attr("data-id")
val servers =
app.get("$zoroAPI/ajax/episode/servers?episodeId=${episodeId ?: return@apmap}", headers = headers)
.parsedSafe<ZoroResponses>()?.html?.let { Jsoup.parse(it) }
app.get("$aniwatchAPI/ajax/v2/episode/servers?episodeId=${episodeId ?: return@apmap}", headers = headers)
.parsedSafe<AniwatchResponses>()?.html?.let { Jsoup.parse(it) }
?.select("div.item.server-item")?.map {
Triple(
it.text(),
@ -1035,22 +1033,21 @@ object SoraExtractor : SoraStream() {
}
servers?.apmap servers@{ server ->
val iframe =
app.get("$zoroAPI/ajax/episode/sources?id=${server.second ?: return@servers}", headers = headers)
.parsedSafe<ZoroResponses>()?.link ?: return@servers
val iframe = app.get("$aniwatchAPI/ajax/v2/episode/sources?id=${server.second ?: return@servers}", headers = headers)
.parsedSafe<AniwatchResponses>()?.link ?: return@servers
val audio = if (server.third == "sub") "Raw" else "English Dub"
if (server.first.contains(Regex("Vidstreaming|MegaCloud|Vidcloud"))) {
extractRabbitStream(
"${server.first} [$audio]",
iframe,
"$zoroAPI/",
"$aniwatchAPI/",
subtitleCallback,
callback,
false,
decryptKey = RabbitStream.getZoroKey()
) { it }
} else {
loadExtractor(iframe, "$zoroAPI/", subtitleCallback, callback)
loadExtractor(iframe, "$aniwatchAPI/", subtitleCallback, callback)
}
}

View File

@ -405,15 +405,15 @@ data class CrunchyrollSourcesResponses(
@JsonProperty("meta") val meta: CrunchyrollMeta? = null,
)
data class MALSyncPages(
data class MALSyncSites(
@JsonProperty("Zoro") val zoro: HashMap<String?, HashMap<String, String?>>? = hashMapOf(),
)
data class MALSyncResponses(
@JsonProperty("Pages") val pages: MALSyncPages? = null,
@JsonProperty("Sites") val sites: MALSyncSites? = null,
)
data class ZoroResponses(
data class AniwatchResponses(
@JsonProperty("html") val html: String? = null,
@JsonProperty("link") val link: String? = null,
)

View File

@ -16,7 +16,6 @@ import com.hexated.SoraExtractor.invokeMovieHab
import com.hexated.SoraExtractor.invokeNoverse
import com.hexated.SoraExtractor.invokeSeries9
import com.hexated.SoraExtractor.invokeVidSrc
import com.hexated.SoraExtractor.invokeXmovies
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
@ -100,7 +99,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 zoroAPI = "https://kaido.to"
const val aniwatchAPI = "https://aniwatch.to"
const val crunchyrollAPI = "https://beta-api.crunchyroll.com"
const val kissKhAPI = "https://kisskh.co"
const val lingAPI = "https://ling-online.net"

View File

@ -21,6 +21,7 @@ import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
@ -578,7 +579,7 @@ suspend fun invokeSmashyIm(
Regex("['\"]?subtitle['\"]?:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1) ?: return
M3u8Helper.generateM3u8(
name,
"Smashy [$name]",
sources,
""
).forEach(callback)
@ -955,7 +956,7 @@ suspend fun searchWatchOnline(
}
//modified code from https://github.com/jmir1/aniyomi-extensions/blob/master/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/AccessTokenInterceptor.kt
fun getCrunchyrollToken(): Map<String, String> {
suspend fun getCrunchyrollToken(): Map<String, String> {
val client = app.baseClient.newBuilder()
.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress("cr-unblocker.us.to", 1080)))
.build()
@ -975,7 +976,7 @@ fun getCrunchyrollToken(): Map<String, String> {
"Authorization" to "Basic ${BuildConfig.CRUNCHYROLL_BASIC_TOKEN}"
),
data = mapOf(
"refresh_token" to BuildConfig.CRUNCHYROLL_REFRESH_TOKEN,
"refresh_token" to app.get(BuildConfig.CRUNCHYROLL_REFRESH_TOKEN).text,
"grant_type" to "refresh_token",
"scope" to "offline_access"
)
@ -1840,8 +1841,8 @@ object RabbitStream {
if (sources == null || encryptedMap.encrypted == false) {
response.parsedSafe()
} else {
val decrypted =
decryptMapped<List<Sources>>(sources, decryptKey)
val (realKey, encData) = extractRealKey(sources, decryptKey)
val decrypted = decryptMapped<List<Sources>>(encData, realKey)
SourceObject(
sources = decrypted,
tracks = encryptedMap.tracks
@ -1984,7 +1985,21 @@ object RabbitStream {
}
suspend fun getZoroKey(): String {
return app.get("https://raw.githubusercontent.com/enimax-anime/key/e0/key.txt").text
return app.get("https://raw.githubusercontent.com/enimax-anime/key/e6/key.txt").text
}
private fun extractRealKey(originalString: String?, stops: String) : Pair<String,String> {
val table = parseJson<List<List<Int>>>(stops)
val decryptedKey = StringBuilder()
var offset = 0
var encryptedString = originalString
table.forEach { (start, end) ->
decryptedKey.append(encryptedString?.substring(start - offset, end - offset))
encryptedString = encryptedString?.substring(0, start - offset) + encryptedString?.substring(end - offset)
offset += end - start
}
return decryptedKey.toString() to encryptedString.toString()
}
private inline fun <reified T> decryptMapped(input: String, key: String): T? {