sora: fix sources

This commit is contained in:
hexated 2023-05-30 01:39:47 +07:00
parent f70d881db0
commit 3702430c02
5 changed files with 97 additions and 44 deletions

View file

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

View file

@ -730,14 +730,14 @@ object SoraExtractor : SoraStream() {
) { ) {
val query = title?.replace(Regex("[^\\w-\\s]"), "") val query = title?.replace(Regex("[^\\w-\\s]"), "")
val html = val html =
app.get("$fmoviesAPI/ajax/film/search?vrf=${encodeVrf("$query")}&keyword=$query") app.get("$fmoviesAPI/ajax/film/search?keyword=$query")
.parsedSafe<FmoviesResponses>()?.html .parsedSafe<FmoviesResponses>()?.result?.html
val mediaId = Jsoup.parse(html ?: return).select("a.item").map { val mediaId = Jsoup.parse(html ?: return).select("a.item").map {
Triple( Triple(
it.attr("href"), it.attr("href"),
it.select("div.title").text(), it.select("div.name").text(),
it.selectFirst("i.dot")?.nextSibling().toString().trim(), it.select("span.dot")[1].text(),
) )
}.find { }.find {
if (season == null) { if (season == null) {
@ -746,38 +746,35 @@ object SoraExtractor : SoraStream() {
it.first.contains("/series/") it.first.contains("/series/")
} && (it.second.equals(title, true) || it.second.createSlug() } && (it.second.equals(title, true) || it.second.createSlug()
.equals(title.createSlug())) && it.third.toInt() == year .equals(title.createSlug())) && it.third.toInt() == year
}?.first?.substringAfterLast("-") ?: return }?.first
val episodeId = if (season == null) { val watchId =
"1-full" app.get(fixUrl(mediaId ?: return, fmoviesAPI)).document.selectFirst("div.watch")
} else { ?.attr("data-id")
"$season-$episode"
}
val serversKname = val episodeId = app.get(
app.get("$fmoviesAPI/ajax/film/servers?id=$mediaId&vrf=${encodeVrf(mediaId)}") "$fmoviesAPI/ajax/episode/list/${watchId ?: return}?vrf=${
.parsedSafe<FmoviesResponses>()?.html?.let { Jsoup.parse(it) } comsumetEncodeVrf(watchId)
?.selectFirst("a[data-kname=$episodeId]")?.attr("data-ep") }"
).parsedSafe<FmoviesResult>()?.result?.let { Jsoup.parse(it) }
?.selectFirst("ul[data-season=${season ?: 1}] li a[data-num=${episode ?: 1}]")
?.attr("data-id")
val servers = tryParseJson<HashMap<String, String>>(serversKname) val servers =
app.get("$fmoviesAPI/ajax/server/list/${episodeId ?: return}?vrf=${comsumetEncodeVrf(episodeId)}")
.parsedSafe<FmoviesResult>()?.result?.let { Jsoup.parse(it) }
?.select("ul li")?.map { it.attr("data-id") to it.attr("data-link-id") }
val sub = app.get("$fmoviesAPI/ajax/episode/subtitles/${servers?.get("28")}").text servers?.filter {
tryParseJson<List<FmoviesSubtitles>>(sub)?.map { it.first == "41" || it.first == "45"
subtitleCallback.invoke( }?.apmap { (serverid, linkId) ->
SubtitleFile( delay(2000)
it.label ?: "", val decryptServer = app.get("$fmoviesAPI/ajax/server/$linkId?vrf=${comsumetEncodeVrf(linkId)}")
it.file ?: return@map .parsedSafe<FmoviesResponses>()?.result?.url?.let { comsumetDecodeVrf(it) }
) if (serverid == "41") {
) invokeVizcloud(serverid, decryptServer ?: return@apmap, subtitleCallback, callback)
}
servers?.apmap { server ->
val decryptServer = app.get("$fmoviesAPI/ajax/episode/info?id=${server.value}")
.parsedSafe<FmoviesResponses>()?.url?.let { decodeVrf(it) } ?: return@apmap
if (server.key == "41") {
invokeVizcloud(decryptServer, callback)
} else { } else {
loadExtractor(decryptServer, fmoviesAPI, subtitleCallback, callback) loadExtractor(decryptServer ?: return@apmap, fmoviesAPI, subtitleCallback, callback)
} }
} }
} }
@ -3236,7 +3233,12 @@ data class DudetvSources(
) )
data class FmoviesResponses( data class FmoviesResponses(
@JsonProperty("result") val result: FmoviesResult? = null,
)
data class FmoviesResult(
@JsonProperty("html") val html: String? = null, @JsonProperty("html") val html: String? = null,
@JsonProperty("result") val result: String? = null,
@JsonProperty("url") val url: String? = null, @JsonProperty("url") val url: String? = null,
) )

View file

@ -78,6 +78,7 @@ open class SoraStream : TmdbProvider() {
const val gdbot = "https://gdtot.pro" const val gdbot = "https://gdtot.pro"
const val anilistAPI = "https://graphql.anilist.co" const val anilistAPI = "https://graphql.anilist.co"
const val malsyncAPI = "https://api.malsync.moe" const val malsyncAPI = "https://api.malsync.moe"
const val consumetHelper = "https://api.consumet.org/anime/9anime/helper"
private val apiKey = private val apiKey =
base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
@ -106,8 +107,8 @@ open class SoraStream : TmdbProvider() {
const val fdMoviesAPI = "https://freedrivemovie.lol" const val fdMoviesAPI = "https://freedrivemovie.lol"
const val m4uhdAPI = "https://m4uhd.tv" const val m4uhdAPI = "https://m4uhd.tv"
const val tvMoviesAPI = "https://www.tvseriesnmovies.com" const val tvMoviesAPI = "https://www.tvseriesnmovies.com"
const val moviezAddAPI = "https://ww1.moviezaddiction.click" const val moviezAddAPI = "https://ww2.moviezaddiction.click"
const val bollyMazaAPI = "https://ww1.bollymaza.click" const val bollyMazaAPI = "https://m.bollymaza.click"
const val moviesbayAPI = "https://moviesbay.live" const val moviesbayAPI = "https://moviesbay.live"
const val rStreamAPI = "https://remotestre.am" const val rStreamAPI = "https://remotestre.am"
const val flixonAPI = "https://flixon.ru" const val flixonAPI = "https://flixon.ru"
@ -117,7 +118,7 @@ open class SoraStream : TmdbProvider() {
const val watchSomuchAPI = "https://watchsomuch.tv" // sub only const val watchSomuchAPI = "https://watchsomuch.tv" // sub only
val gomoviesAPI = val gomoviesAPI =
base64DecodeAPI("bQ==Y28=ZS4=aW4=bmw=LW8=ZXM=dmk=bW8=Z28=Ly8=czo=dHA=aHQ=") base64DecodeAPI("bQ==Y28=ZS4=aW4=bmw=LW8=ZXM=dmk=bW8=Z28=Ly8=czo=dHA=aHQ=")
const val ask4MoviesAPI = "https://ask4movie.mx" const val ask4MoviesAPI = "https://ask4movie.net"
const val biliBiliAPI = "https://api-vn.kaguya.app/server" const val biliBiliAPI = "https://api-vn.kaguya.app/server"
const val watchOnlineAPI = "https://watchonline.ag" const val watchOnlineAPI = "https://watchonline.ag"
const val nineTvAPI = "https://api.9animetv.live" const val nineTvAPI = "https://api.9animetv.live"
@ -140,7 +141,6 @@ open class SoraStream : TmdbProvider() {
base64DecodeAPI("ZXY=LmQ=cnM=a2U=b3I=Lnc=ZXI=ZGQ=bGE=cy0=b2I=YWM=Lmo=YWw=aW4=LWY=cm4=Ym8=cmU=Ly8=czo=dHA=aHQ=") base64DecodeAPI("ZXY=LmQ=cnM=a2U=b3I=Lnc=ZXI=ZGQ=bGE=cy0=b2I=YWM=Lmo=YWw=aW4=LWY=cm4=Ym8=cmU=Ly8=czo=dHA=aHQ=")
// DEAD SITE // DEAD SITE
const val consumetCrunchyrollAPI = "https://cronchy.consumet.stream" // dead
const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead
const val chillmovies1API = "https://chill.aicirou.workers.dev/1:" // dead const val chillmovies1API = "https://chill.aicirou.workers.dev/1:" // dead
const val gamMoviesAPI = "https://drive.gamick.workers.dev/0:" // dead const val gamMoviesAPI = "https://drive.gamick.workers.dev/0:" // dead
@ -503,7 +503,7 @@ open class SoraStream : TmdbProvider() {
) )
}, },
{ {
invokeFmovies( if (!res.isAnime) invokeFmovies(
res.title, res.title,
res.airedYear ?: res.year, res.airedYear ?: res.year,
res.season, res.season,
@ -610,7 +610,14 @@ open class SoraStream : TmdbProvider() {
invokeMovie123Net(res.title, res.season, res.episode, subtitleCallback, callback) invokeMovie123Net(res.title, res.season, res.episode, subtitleCallback, callback)
}, },
{ {
invokeSmashyStream(res.imdbId, res.season, res.episode, res.isAnime, subtitleCallback, callback) invokeSmashyStream(
res.imdbId,
res.season,
res.episode,
res.isAnime,
subtitleCallback,
callback
)
}, },
{ {
invokeWatchsomuch( invokeWatchsomuch(

View file

@ -145,7 +145,14 @@ class SoraStreamLite : SoraStream() {
) )
}, },
{ {
invokeSeries9(res.title, res.year, res.season, res.episode, subtitleCallback, callback) invokeSeries9(
res.title,
res.year,
res.season,
res.episode,
subtitleCallback,
callback
)
}, },
{ {
invokeIdlix( invokeIdlix(
@ -168,13 +175,26 @@ class SoraStreamLite : SoraStream() {
// ) // )
// }, // },
{ {
if (!res.isAnime) invokeFilmxy(res.imdbId, res.season, res.episode, subtitleCallback, callback) if (!res.isAnime) invokeFilmxy(
res.imdbId,
res.season,
res.episode,
subtitleCallback,
callback
)
}, },
{ {
invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback) invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback)
}, },
{ {
invokeSmashyStream(res.imdbId, res.season, res.episode, res.isAnime, subtitleCallback, callback) invokeSmashyStream(
res.imdbId,
res.season,
res.episode,
res.isAnime,
subtitleCallback,
callback
)
}, },
{ {
invokeXmovies( invokeXmovies(
@ -187,7 +207,7 @@ class SoraStreamLite : SoraStream() {
) )
}, },
{ {
invokeFmovies( if (!res.isAnime) invokeFmovies(
res.title, res.title,
res.airedYear ?: res.year, res.airedYear ?: res.year,
res.season, res.season,

View file

@ -5,8 +5,10 @@ import com.fasterxml.jackson.annotation.JsonProperty
import com.hexated.SoraStream.Companion.anilistAPI import com.hexated.SoraStream.Companion.anilistAPI
import com.hexated.SoraStream.Companion.base64DecodeAPI import com.hexated.SoraStream.Companion.base64DecodeAPI
import com.hexated.SoraStream.Companion.baymoviesAPI import com.hexated.SoraStream.Companion.baymoviesAPI
import com.hexated.SoraStream.Companion.consumetHelper
import com.hexated.SoraStream.Companion.crunchyrollAPI import com.hexated.SoraStream.Companion.crunchyrollAPI
import com.hexated.SoraStream.Companion.filmxyAPI import com.hexated.SoraStream.Companion.filmxyAPI
import com.hexated.SoraStream.Companion.fmoviesAPI
import com.hexated.SoraStream.Companion.gdbot import com.hexated.SoraStream.Companion.gdbot
import com.hexated.SoraStream.Companion.malsyncAPI import com.hexated.SoraStream.Companion.malsyncAPI
import com.hexated.SoraStream.Companion.putlockerAPI import com.hexated.SoraStream.Companion.putlockerAPI
@ -400,11 +402,13 @@ suspend fun getDirectGdrive(url: String): String {
} }
suspend fun invokeVizcloud( suspend fun invokeVizcloud(
serverid: String,
url: String, url: String,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit, callback: (ExtractorLink) -> Unit,
) { ) {
val id = Regex("(?:embed-|/e/)([^?]*)").find(url)?.groupValues?.getOrNull(1) val id = Regex("(?:/embed[-/]|/e/)([^?/]*)").find(url)?.groupValues?.getOrNull(1)
app.get("https://api.consumet.org/anime/9anime/helper?query=${id ?: return}&action=vizcloud") app.get("$consumetHelper?query=${id ?: return}&action=vizcloud")
.parsedSafe<VizcloudResponses>()?.data?.media?.sources?.map { .parsedSafe<VizcloudResponses>()?.data?.media?.sources?.map {
M3u8Helper.generateM3u8( M3u8Helper.generateM3u8(
"Vizcloud", "Vizcloud",
@ -412,6 +416,16 @@ suspend fun invokeVizcloud(
"${getBaseUrl(url)}/" "${getBaseUrl(url)}/"
).forEach(callback) ).forEach(callback)
} }
val sub = app.get("${fmoviesAPI}/ajax/episode/subtitles/$serverid")
tryParseJson<List<FmoviesSubtitles>>(sub.text)?.map {
subtitleCallback.invoke(
SubtitleFile(
it.label ?: "",
it.file ?: return@map
)
)
}
} }
suspend fun invokeSmashyFfix( suspend fun invokeSmashyFfix(
@ -1357,6 +1371,16 @@ fun getDeviceId(length: Int = 16): String {
.joinToString("") .joinToString("")
} }
suspend fun comsumetEncodeVrf(query: String): String? {
return app.get("$consumetHelper?query=$query&action=fmovies-vrf")
.parsedSafe<Map<String, String>>()?.get("url")
}
suspend fun comsumetDecodeVrf(query: String): String? {
val res = app.get("$consumetHelper?query=$query&action=fmovies-decrypt")
return tryParseJson<Map<String, String>>(res.text)?.get("url")
}
fun encodeVrf(query: String): String { fun encodeVrf(query: String): String {
return encode( return encode(
encryptVrf( encryptVrf(