mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora: fix sources
This commit is contained in:
parent
f70d881db0
commit
3702430c02
5 changed files with 97 additions and 44 deletions
|
@ -1,7 +1,7 @@
|
|||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
|
||||
// use an integer for version numbers
|
||||
version = 134
|
||||
version = 135
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
|
|
|
@ -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"
|
||||
val watchId =
|
||||
app.get(fixUrl(mediaId ?: return, fmoviesAPI)).document.selectFirst("div.watch")
|
||||
?.attr("data-id")
|
||||
|
||||
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 =
|
||||
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") }
|
||||
|
||||
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 {
|
||||
"$season-$episode"
|
||||
}
|
||||
|
||||
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 servers = tryParseJson<HashMap<String, String>>(serversKname)
|
||||
|
||||
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)
|
||||
} 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,
|
||||
)
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue