mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora: fixed shinobiMovie
This commit is contained in:
parent
511ee5febe
commit
352a0c4f41
6 changed files with 13 additions and 178 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 112
|
version = 113
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -91,16 +91,6 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeOlgply(
|
|
||||||
id: Int? = null,
|
|
||||||
season: Int? = null,
|
|
||||||
episode: Int? = null,
|
|
||||||
callback: (ExtractorLink) -> Unit
|
|
||||||
) {
|
|
||||||
val url = "$olgplyAPI/${id}${season?.let { "/$it" } ?: ""}${episode?.let { "/$it" } ?: ""}"
|
|
||||||
loadLinksWithWebView(url, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun invokeDbgo(
|
suspend fun invokeDbgo(
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
season: Int? = null,
|
season: Int? = null,
|
||||||
|
@ -1652,73 +1642,6 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeKickassanime(
|
|
||||||
title: String? = null,
|
|
||||||
epsTitle: String? = null,
|
|
||||||
season: Int? = null,
|
|
||||||
episode: Int? = null,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit
|
|
||||||
) {
|
|
||||||
val body = """{"query":"$title"}""".toRequestBody(
|
|
||||||
RequestBodyTypes.JSON.toMediaTypeOrNull()
|
|
||||||
)
|
|
||||||
val animeId = app.post(
|
|
||||||
"$kickassanimeAPI/api/search", requestBody = body
|
|
||||||
).text.let { tryParseJson<List<KaaSearchResponse>>(it) }.let { res ->
|
|
||||||
(if (res?.size == 1) {
|
|
||||||
res.firstOrNull()
|
|
||||||
} else {
|
|
||||||
res?.find {
|
|
||||||
it.title?.equals(
|
|
||||||
title,
|
|
||||||
true
|
|
||||||
) == true || it.title.createSlug()
|
|
||||||
?.equals("${title.createSlug()}", true) == true
|
|
||||||
}
|
|
||||||
})?._id
|
|
||||||
} ?: return
|
|
||||||
|
|
||||||
val seasonData =
|
|
||||||
app.get("$kickassanimeAPI/api/season/$animeId").text.let {
|
|
||||||
tryParseJson<List<KaaSeason>>(
|
|
||||||
it
|
|
||||||
)
|
|
||||||
}?.find {
|
|
||||||
val seasonNumber = when (title) {
|
|
||||||
"One Piece" -> 13
|
|
||||||
"Hunter x Hunter" -> 5
|
|
||||||
else -> season
|
|
||||||
}
|
|
||||||
it.number == seasonNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
val language = seasonData?.languages?.filter {
|
|
||||||
it == "ja-JP" || it == "en-US"
|
|
||||||
}
|
|
||||||
|
|
||||||
language?.apmap { lang ->
|
|
||||||
val episodeSlug =
|
|
||||||
app.get("$kickassanimeAPI/api/episodes/${seasonData.id}?lh=$lang&page=1")
|
|
||||||
.parsedSafe<KaaEpisodeResults>()?.result?.find { eps ->
|
|
||||||
eps.episodeNumber == episode || eps.slug?.contains(
|
|
||||||
"${epsTitle.createSlug()}",
|
|
||||||
true
|
|
||||||
) == true
|
|
||||||
}?.slug ?: return@apmap
|
|
||||||
|
|
||||||
val server = app.get("$kickassanimeAPI/api/watch/$episodeSlug")
|
|
||||||
.parsedSafe<KaaServers>()?.servers?.find {
|
|
||||||
it.contains("/sapphire-duck/")
|
|
||||||
} ?: return@apmap
|
|
||||||
|
|
||||||
invokeSapphire(server, lang == "en-US", subtitleCallback, callback)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun invokeMoviesbay(
|
suspend fun invokeMoviesbay(
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
year: Int? = null,
|
year: Int? = null,
|
||||||
|
@ -2428,7 +2351,8 @@ object SoraExtractor : SoraStream() {
|
||||||
}).text.let { path ->
|
}).text.let { path ->
|
||||||
if (api in ddomainIndex) {
|
if (api in ddomainIndex) {
|
||||||
val worker = app.get(
|
val worker = app.get(
|
||||||
"${fixUrl(path, apiUrl)}?a=view"
|
"${fixUrl(path, apiUrl).encodeUrl()}?a=view",
|
||||||
|
referer = if(api in needRefererIndex) apiUrl else ""
|
||||||
).document.selectFirst("script:containsData(downloaddomain)")?.data()
|
).document.selectFirst("script:containsData(downloaddomain)")?.data()
|
||||||
?.substringAfter("\"downloaddomain\":\"")?.substringBefore("\",")?.let {
|
?.substringAfter("\"downloaddomain\":\"")?.substringBefore("\",")?.let {
|
||||||
"$it/0:"
|
"$it/0:"
|
||||||
|
@ -2796,19 +2720,19 @@ object SoraExtractor : SoraStream() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeCoatomotate(
|
invokeMonster(
|
||||||
res.url.substringAfterLast("/"), episodeId, season, callback
|
res.url.substringAfterLast("/"), episodeId, season, callback
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeCoatomotate(
|
private suspend fun invokeMonster(
|
||||||
urlSlug: String? = null,
|
urlSlug: String? = null,
|
||||||
episodeId: String? = null,
|
episodeId: String? = null,
|
||||||
season: Int? = null,
|
season: Int? = null,
|
||||||
callback: (ExtractorLink) -> Unit,
|
callback: (ExtractorLink) -> Unit,
|
||||||
) {
|
) {
|
||||||
val coaMainUrl = "https://coatomotate.monster"
|
val monsterMainUrl = "https://dignes.monster"
|
||||||
val playSlug = if (season == null) {
|
val playSlug = if (season == null) {
|
||||||
"movies/play/$urlSlug"
|
"movies/play/$urlSlug"
|
||||||
} else {
|
} else {
|
||||||
|
@ -2816,16 +2740,16 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
val sid = "9k9iupt5sebbnfajrc6ti3ht7l"
|
val sid = "9k9iupt5sebbnfajrc6ti3ht7l"
|
||||||
val sec = "1974bc4a902c4d69fcbab261dcec69094a9b8164"
|
val sec = "1974bc4a902c4d69fcbab261dcec69094a9b8164"
|
||||||
val url = "$coaMainUrl/$playSlug?mid=1&sid=$sid&sec=$sec&t=${System.currentTimeMillis()}"
|
val url = "$monsterMainUrl/$playSlug?mid=1&sid=$sid&sec=$sec&t=${System.currentTimeMillis()}"
|
||||||
val res = app.get(url).document
|
val res = app.get(url).document
|
||||||
val script = res.selectFirst("script:containsData(window['show_storage'])")?.data()
|
val script = res.selectFirst("script:containsData(window['show_storage'])")?.data()
|
||||||
val hash = Regex("hash:\\s*['\"](\\S+)['\"],").find(script ?: return)?.groupValues?.get(1)
|
val hash = Regex("hash:\\s*['\"](\\S+)['\"],").find(script ?: return)?.groupValues?.get(1)
|
||||||
val expires = Regex("expires:\\s*(\\d+),").find(script ?: return)?.groupValues?.get(1)
|
val expires = Regex("expires:\\s*(\\d+),").find(script ?: return)?.groupValues?.get(1)
|
||||||
|
|
||||||
val videoUrl = if (season == null) {
|
val videoUrl = if (season == null) {
|
||||||
"$coaMainUrl/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires"
|
"$monsterMainUrl/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires"
|
||||||
} else {
|
} else {
|
||||||
"$coaMainUrl/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires"
|
"$monsterMainUrl/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires"
|
||||||
}
|
}
|
||||||
|
|
||||||
app.get(videoUrl, referer = url)
|
app.get(videoUrl, referer = url)
|
||||||
|
@ -2835,7 +2759,7 @@ object SoraExtractor : SoraStream() {
|
||||||
"WatchOnline",
|
"WatchOnline",
|
||||||
"WatchOnline",
|
"WatchOnline",
|
||||||
source.value,
|
source.value,
|
||||||
"$coaMainUrl/",
|
"$monsterMainUrl/",
|
||||||
getQualityFromName(source.key),
|
getQualityFromName(source.key),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
@ -3161,30 +3085,6 @@ data class SorastreamVideos(
|
||||||
@JsonProperty("currentDefinition") val currentDefinition: String? = null,
|
@JsonProperty("currentDefinition") val currentDefinition: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class KaaServers(
|
|
||||||
@JsonProperty("servers") val servers: ArrayList<String>? = arrayListOf(),
|
|
||||||
)
|
|
||||||
|
|
||||||
data class KaaEpisode(
|
|
||||||
@JsonProperty("episodeNumber") val episodeNumber: Int? = null,
|
|
||||||
@JsonProperty("slug") val slug: String? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class KaaEpisodeResults(
|
|
||||||
@JsonProperty("result") val result: ArrayList<KaaEpisode>? = arrayListOf(),
|
|
||||||
)
|
|
||||||
|
|
||||||
data class KaaSeason(
|
|
||||||
@JsonProperty("id") val id: String? = null,
|
|
||||||
@JsonProperty("number") val number: Int? = null,
|
|
||||||
@JsonProperty("languages") val languages: ArrayList<String>? = arrayListOf(),
|
|
||||||
)
|
|
||||||
|
|
||||||
data class KaaSearchResponse(
|
|
||||||
@JsonProperty("_id") val _id: String? = null,
|
|
||||||
@JsonProperty("title") val title: String? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class SapphireSubtitles(
|
data class SapphireSubtitles(
|
||||||
@JsonProperty("language") val language: String? = null,
|
@JsonProperty("language") val language: String? = null,
|
||||||
@JsonProperty("url") val url: String? = null,
|
@JsonProperty("url") val url: String? = null,
|
||||||
|
|
|
@ -92,7 +92,6 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val series9API = "https://series9.la"
|
const val series9API = "https://series9.la"
|
||||||
const val idlixAPI = "https://idlixian.com"
|
const val idlixAPI = "https://idlixian.com"
|
||||||
const val noverseAPI = "https://www.nollyverse.com"
|
const val noverseAPI = "https://www.nollyverse.com"
|
||||||
const val olgplyAPI = "https://olgply.xyz" // dead
|
|
||||||
const val uniqueStreamAPI = "https://uniquestream.net"
|
const val uniqueStreamAPI = "https://uniquestream.net"
|
||||||
const val filmxyAPI = "https://www.filmxy.vip"
|
const val filmxyAPI = "https://www.filmxy.vip"
|
||||||
const val kimcartoonAPI = "https://kimcartoon.li"
|
const val kimcartoonAPI = "https://kimcartoon.li"
|
||||||
|
@ -100,7 +99,6 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val haikeiFlixhqAPI = "https://api.haikei.xyz/movies/flixhq" // disabled due to rate limit
|
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 consumetZoroAPI = "https://api.consumet.org/anime/zoro"
|
||||||
const val consumetCrunchyrollAPI = "https://cronchy.consumet.stream"
|
const val consumetCrunchyrollAPI = "https://cronchy.consumet.stream"
|
||||||
const val kickassanimeAPI = "https://www2.kickassanime.ro" // disabled due to consumet
|
|
||||||
const val kissKhAPI = "https://kisskh.me"
|
const val kissKhAPI = "https://kisskh.me"
|
||||||
const val lingAPI = "https://ling-online.net"
|
const val lingAPI = "https://ling-online.net"
|
||||||
const val uhdmoviesAPI = "https://uhdmovies.vip"
|
const val uhdmoviesAPI = "https://uhdmovies.vip"
|
||||||
|
@ -115,7 +113,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val rStreamAPI = "https://remotestre.am"
|
const val rStreamAPI = "https://remotestre.am"
|
||||||
const val flixonAPI = "https://flixon.ru"
|
const val flixonAPI = "https://flixon.ru"
|
||||||
const val animeKaizokuAPI = "https://animekaizoku.com"
|
const val animeKaizokuAPI = "https://animekaizoku.com"
|
||||||
const val movie123NetAPI = "https://ww7.0123movie.net"
|
const val movie123NetAPI = "https://ww8.0123movie.net"
|
||||||
const val smashyStreamAPI = "https://embed.smashystream.com"
|
const val smashyStreamAPI = "https://embed.smashystream.com"
|
||||||
const val watchSomuchAPI = "https://watchsomuch.tv" // sub only
|
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=")
|
val gomoviesAPI = base64DecodeAPI("bQ==Y28=ZS4=aW4=bmw=LW8=ZXM=dmk=bW8=Z28=Ly8=czo=dHA=aHQ=")
|
||||||
|
@ -376,9 +374,6 @@ open class SoraStream : TmdbProvider() {
|
||||||
{
|
{
|
||||||
invokeVidSrc(res.id, res.season, res.episode, subtitleCallback, callback)
|
invokeVidSrc(res.id, res.season, res.episode, subtitleCallback, callback)
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// invokeOlgply(res.id, res.season, res.episode, callback)
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
invokeDbgo(res.imdbId, res.season, res.episode, subtitleCallback, callback)
|
invokeDbgo(res.imdbId, res.season, res.episode, subtitleCallback, callback)
|
||||||
},
|
},
|
||||||
|
|
|
@ -513,42 +513,6 @@ suspend fun fetchSoraEpisodes(id: String, type: String, episode: Int?) : Episode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeSapphire(
|
|
||||||
url: String? = null,
|
|
||||||
isDub: Boolean = false,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit,
|
|
||||||
) {
|
|
||||||
var data = app.get("${url?.replace("player.php", "config.php")}&action=config", referer = url).text
|
|
||||||
while (true) {
|
|
||||||
if (data.startsWith("{")) break
|
|
||||||
if (data == "null") {
|
|
||||||
data = app.get("$url&action=config", referer = url).text
|
|
||||||
delay(1000)
|
|
||||||
}
|
|
||||||
data = data.decodeBase64()
|
|
||||||
}
|
|
||||||
|
|
||||||
tryParseJson<SapphireSources>(data).let { res ->
|
|
||||||
res?.streams?.filter { it.format == "adaptive_hls" && it.hardsub_lang.isNullOrEmpty() }?.reversed()?.map { source ->
|
|
||||||
val name = if (isDub) "English Dub" else "Raw"
|
|
||||||
M3u8Helper.generateM3u8(
|
|
||||||
"Crunchyroll [$name]",
|
|
||||||
source.url ?: return@map null,
|
|
||||||
"https://static.crunchyroll.com/",
|
|
||||||
).forEach(callback)
|
|
||||||
}
|
|
||||||
res?.subtitles?.map { sub ->
|
|
||||||
subtitleCallback.invoke(
|
|
||||||
SubtitleFile(
|
|
||||||
fixCrunchyrollLang(sub.language ?: return@map null) ?: sub.language,
|
|
||||||
sub.url ?: return@map null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun bypassOuo(url: String?): String? {
|
suspend fun bypassOuo(url: String?): String? {
|
||||||
var res = session.get(url ?: return null)
|
var res = session.get(url ?: return null)
|
||||||
run lit@{
|
run lit@{
|
||||||
|
@ -1163,30 +1127,6 @@ fun fixUrl(url: String, domain: String): String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun loadLinksWithWebView(
|
|
||||||
url: String,
|
|
||||||
callback: (ExtractorLink) -> Unit
|
|
||||||
) {
|
|
||||||
val foundVideo = WebViewResolver(
|
|
||||||
Regex("""\.m3u8|i7njdjvszykaieynzsogaysdgb0hm8u1mzubmush4maopa4wde\.com""")
|
|
||||||
).resolveUsingWebView(
|
|
||||||
requestCreator(
|
|
||||||
"GET", url, referer = "https://olgply.com/"
|
|
||||||
)
|
|
||||||
).first ?: return
|
|
||||||
|
|
||||||
callback.invoke(
|
|
||||||
ExtractorLink(
|
|
||||||
"Olgply",
|
|
||||||
"Olgply",
|
|
||||||
foundVideo.url.toString(),
|
|
||||||
"",
|
|
||||||
Qualities.P1080.value,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Int.toRomanNumeral(): String = Symbol.closestBelow(this)
|
fun Int.toRomanNumeral(): String = Symbol.closestBelow(this)
|
||||||
.let { symbol ->
|
.let { symbol ->
|
||||||
if (symbol != null) {
|
if (symbol != null) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 5
|
version = 6
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.jsoup.nodes.Element
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class YugenAnime : MainAPI() {
|
class YugenAnime : MainAPI() {
|
||||||
override var mainUrl = "https://yugenanime.ro"
|
override var mainUrl = "https://yugen.to"
|
||||||
override var name = "YugenAnime"
|
override var name = "YugenAnime"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override var lang = "en"
|
override var lang = "en"
|
||||||
|
|
Loading…
Reference in a new issue