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
// use an integer for version numbers
version = 134
version = 135
android {
defaultConfig {

View File

@ -730,14 +730,14 @@ object SoraExtractor : SoraStream() {
) {
val query = title?.replace(Regex("[^\\w-\\s]"), "")
val html =
app.get("$fmoviesAPI/ajax/film/search?vrf=${encodeVrf("$query")}&keyword=$query")
.parsedSafe<FmoviesResponses>()?.html
app.get("$fmoviesAPI/ajax/film/search?keyword=$query")
.parsedSafe<FmoviesResponses>()?.result?.html
val mediaId = Jsoup.parse(html ?: return).select("a.item").map {
Triple(
it.attr("href"),
it.select("div.title").text(),
it.selectFirst("i.dot")?.nextSibling().toString().trim(),
it.select("div.name").text(),
it.select("span.dot")[1].text(),
)
}.find {
if (season == null) {
@ -746,38 +746,35 @@ object SoraExtractor : SoraStream() {
it.first.contains("/series/")
} && (it.second.equals(title, true) || it.second.createSlug()
.equals(title.createSlug())) && it.third.toInt() == year
}?.first?.substringAfterLast("-") ?: return
}?.first
val episodeId = if (season == null) {
"1-full"
} else {
"$season-$episode"
}
val watchId =
app.get(fixUrl(mediaId ?: return, fmoviesAPI)).document.selectFirst("div.watch")
?.attr("data-id")
val serversKname =
app.get("$fmoviesAPI/ajax/film/servers?id=$mediaId&vrf=${encodeVrf(mediaId)}")
.parsedSafe<FmoviesResponses>()?.html?.let { Jsoup.parse(it) }
?.selectFirst("a[data-kname=$episodeId]")?.attr("data-ep")
val episodeId = app.get(
"$fmoviesAPI/ajax/episode/list/${watchId ?: return}?vrf=${
comsumetEncodeVrf(watchId)
}"
).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
tryParseJson<List<FmoviesSubtitles>>(sub)?.map {
subtitleCallback.invoke(
SubtitleFile(
it.label ?: "",
it.file ?: return@map
)
)
}
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)
servers?.filter {
it.first == "41" || it.first == "45"
}?.apmap { (serverid, linkId) ->
delay(2000)
val decryptServer = app.get("$fmoviesAPI/ajax/server/$linkId?vrf=${comsumetEncodeVrf(linkId)}")
.parsedSafe<FmoviesResponses>()?.result?.url?.let { comsumetDecodeVrf(it) }
if (serverid == "41") {
invokeVizcloud(serverid, decryptServer ?: return@apmap, subtitleCallback, callback)
} else {
loadExtractor(decryptServer, fmoviesAPI, subtitleCallback, callback)
loadExtractor(decryptServer ?: return@apmap, fmoviesAPI, subtitleCallback, callback)
}
}
}
@ -3236,7 +3233,12 @@ data class DudetvSources(
)
data class FmoviesResponses(
@JsonProperty("result") val result: FmoviesResult? = null,
)
data class FmoviesResult(
@JsonProperty("html") val html: String? = null,
@JsonProperty("result") val result: 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 anilistAPI = "https://graphql.anilist.co"
const val malsyncAPI = "https://api.malsync.moe"
const val consumetHelper = "https://api.consumet.org/anime/9anime/helper"
private val apiKey =
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 m4uhdAPI = "https://m4uhd.tv"
const val tvMoviesAPI = "https://www.tvseriesnmovies.com"
const val moviezAddAPI = "https://ww1.moviezaddiction.click"
const val bollyMazaAPI = "https://ww1.bollymaza.click"
const val moviezAddAPI = "https://ww2.moviezaddiction.click"
const val bollyMazaAPI = "https://m.bollymaza.click"
const val moviesbayAPI = "https://moviesbay.live"
const val rStreamAPI = "https://remotestre.am"
const val flixonAPI = "https://flixon.ru"
@ -117,7 +118,7 @@ open class SoraStream : TmdbProvider() {
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=")
const val ask4MoviesAPI = "https://ask4movie.mx"
const val ask4MoviesAPI = "https://ask4movie.net"
const val biliBiliAPI = "https://api-vn.kaguya.app/server"
const val watchOnlineAPI = "https://watchonline.ag"
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=")
// DEAD SITE
const val consumetCrunchyrollAPI = "https://cronchy.consumet.stream" // dead
const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead
const val chillmovies1API = "https://chill.aicirou.workers.dev/1:" // 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.airedYear ?: res.year,
res.season,
@ -610,7 +610,14 @@ open class SoraStream : TmdbProvider() {
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(

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(
@ -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)
},
{
invokeSmashyStream(res.imdbId, res.season, res.episode, res.isAnime, subtitleCallback, callback)
invokeSmashyStream(
res.imdbId,
res.season,
res.episode,
res.isAnime,
subtitleCallback,
callback
)
},
{
invokeXmovies(
@ -187,7 +207,7 @@ class SoraStreamLite : SoraStream() {
)
},
{
invokeFmovies(
if (!res.isAnime) invokeFmovies(
res.title,
res.airedYear ?: res.year,
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.base64DecodeAPI
import com.hexated.SoraStream.Companion.baymoviesAPI
import com.hexated.SoraStream.Companion.consumetHelper
import com.hexated.SoraStream.Companion.crunchyrollAPI
import com.hexated.SoraStream.Companion.filmxyAPI
import com.hexated.SoraStream.Companion.fmoviesAPI
import com.hexated.SoraStream.Companion.gdbot
import com.hexated.SoraStream.Companion.malsyncAPI
import com.hexated.SoraStream.Companion.putlockerAPI
@ -400,11 +402,13 @@ suspend fun getDirectGdrive(url: String): String {
}
suspend fun invokeVizcloud(
serverid: String,
url: String,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit,
) {
val id = Regex("(?:embed-|/e/)([^?]*)").find(url)?.groupValues?.getOrNull(1)
app.get("https://api.consumet.org/anime/9anime/helper?query=${id ?: return}&action=vizcloud")
val id = Regex("(?:/embed[-/]|/e/)([^?/]*)").find(url)?.groupValues?.getOrNull(1)
app.get("$consumetHelper?query=${id ?: return}&action=vizcloud")
.parsedSafe<VizcloudResponses>()?.data?.media?.sources?.map {
M3u8Helper.generateM3u8(
"Vizcloud",
@ -412,6 +416,16 @@ suspend fun invokeVizcloud(
"${getBaseUrl(url)}/"
).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(
@ -1357,6 +1371,16 @@ fun getDeviceId(length: Int = 16): String {
.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 {
return encode(
encryptVrf(