mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
fixed shinobi in sora & fixed Hdfilmcehennemi title
This commit is contained in:
parent
c82488fcbc
commit
97df334b18
8 changed files with 134 additions and 57 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 6
|
version = 7
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Hdfilmcehennemi : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Element.toSearchResult(): SearchResponse? {
|
private fun Element.toSearchResult(): SearchResponse? {
|
||||||
val title = this.selectFirst("a")?.text() ?: return null
|
val title = this.selectFirst("h2.title")?.text() ?: return null
|
||||||
val href = fixUrlNull(this.selectFirst("a")?.attr("href")) ?: return null
|
val href = fixUrlNull(this.selectFirst("a")?.attr("href")) ?: return null
|
||||||
val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("data-src"))
|
val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("data-src"))
|
||||||
return newMovieSearchResponse(title, href, TvType.Movie) {
|
return newMovieSearchResponse(title, href, TvType.Movie) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 8
|
version = 9
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 95
|
version = 96
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -709,61 +709,30 @@ object SoraExtractor : SoraStream() {
|
||||||
season: Int? = null,
|
season: Int? = null,
|
||||||
episode: Int? = null,
|
episode: Int? = null,
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit,
|
|
||||||
) {
|
) {
|
||||||
val headers = mapOf(
|
val (id, type) = getSoraIdAndType(title, year, season) ?: return
|
||||||
"lang" to "en",
|
val json = fetchSoraEpisodes(id, type, episode) ?: return
|
||||||
"versioncode" to "32",
|
|
||||||
"clienttype" to "android_tem3",
|
|
||||||
)
|
|
||||||
val vipAPI =
|
|
||||||
base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
|
|
||||||
val searchUrl = base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")
|
|
||||||
|
|
||||||
val doc = app.get("$searchUrl/search?keyword=$title").document
|
json.subtitlingList?.map { sub ->
|
||||||
|
subtitleCallback.invoke(
|
||||||
val scriptData = doc.select("div.search-list div.search-video-card").map {
|
SubtitleFile(
|
||||||
Triple(
|
getVipLanguage(sub.languageAbbr ?: return@map),
|
||||||
it.selectFirst("h2.title")?.text().toString(),
|
sub.subtitlingUrl ?: return@map
|
||||||
it.selectFirst("div.desc")?.text()
|
)
|
||||||
?.substringBefore(".")?.toIntOrNull(),
|
|
||||||
it.selectFirst("a")?.attr("href")?.split("/")
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val script = if (scriptData.size == 1) {
|
suspend fun invokeSoraStreamLite(
|
||||||
scriptData.firstOrNull()
|
title: String? = null,
|
||||||
} else {
|
year: Int? = null,
|
||||||
scriptData.find {
|
season: Int? = null,
|
||||||
when (season) {
|
episode: Int? = null,
|
||||||
null -> {
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
it.first.equals(
|
callback: (ExtractorLink) -> Unit,
|
||||||
title,
|
) {
|
||||||
true
|
val (id, type) = getSoraIdAndType(title, year, season) ?: return
|
||||||
) && it.second == year
|
val json = fetchSoraEpisodes(id, type, episode) ?: return
|
||||||
}
|
|
||||||
1 -> {
|
|
||||||
it.first.contains(
|
|
||||||
"$title",
|
|
||||||
true
|
|
||||||
) && (it.second == year || it.first.contains("Season $season", true))
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
it.first.contains(Regex("(?i)$title\\s?($season|${season.toRomanNumeral()}|Season\\s$season)")) && it.second == year
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val id = script?.third?.last() ?: return
|
|
||||||
val type = script.third?.get(2) ?: return
|
|
||||||
|
|
||||||
val json = app.get(
|
|
||||||
"$vipAPI/movieDrama/get?id=${id}&category=${type}",
|
|
||||||
headers = headers
|
|
||||||
).parsedSafe<Load>()?.data?.episodeVo?.find {
|
|
||||||
it.seriesNo == (episode ?: 0)
|
|
||||||
} ?: return
|
|
||||||
|
|
||||||
json.subtitlingList?.map { sub ->
|
json.subtitlingList?.map { sub ->
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
|
@ -774,6 +743,23 @@ object SoraExtractor : SoraStream() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json.definitionList?.map { video ->
|
||||||
|
val media = app.get(
|
||||||
|
"${soraAPI}/media/previewInfo?category=${type}&contentId=${id}&episodeId=${json.id}&definition=${video.code}",
|
||||||
|
headers = soraHeaders,
|
||||||
|
).parsedSafe<SorastreamResponse>()?.data
|
||||||
|
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
this.name,
|
||||||
|
this.name,
|
||||||
|
media?.mediaUrl ?: return@map null,
|
||||||
|
"",
|
||||||
|
getSoraQuality(media.currentDefinition ?: ""),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeXmovies(
|
suspend fun invokeXmovies(
|
||||||
|
@ -2415,7 +2401,7 @@ object SoraExtractor : SoraStream() {
|
||||||
"$api $tags [$size]",
|
"$api $tags [$size]",
|
||||||
"$api $tags [$size]",
|
"$api $tags [$size]",
|
||||||
path,
|
path,
|
||||||
"",
|
if(api in needRefererIndex) apiUrl else "",
|
||||||
quality,
|
quality,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -2926,4 +2912,13 @@ data class TgarData(
|
||||||
|
|
||||||
data class Gdflix(
|
data class Gdflix(
|
||||||
@JsonProperty("url") val url: String
|
@JsonProperty("url") val url: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SorastreamResponse(
|
||||||
|
@JsonProperty("data") val data: SorastreamVideos? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SorastreamVideos(
|
||||||
|
@JsonProperty("mediaUrl") val mediaUrl: String? = null,
|
||||||
|
@JsonProperty("currentDefinition") val currentDefinition: String? = null,
|
||||||
)
|
)
|
|
@ -168,6 +168,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=453" to "Hulu",
|
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=453" to "Hulu",
|
||||||
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=2552" to "Apple TV+",
|
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=2552" to "Apple TV+",
|
||||||
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=49" to "HBO",
|
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=49" to "HBO",
|
||||||
|
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=4330" to "Paramount+",
|
||||||
"$tmdbAPI/movie/top_rated?api_key=$apiKey®ion=US" to "Top Rated Movies",
|
"$tmdbAPI/movie/top_rated?api_key=$apiKey®ion=US" to "Top Rated Movies",
|
||||||
"$tmdbAPI/tv/top_rated?api_key=$apiKey®ion=US" to "Top Rated TV Shows",
|
"$tmdbAPI/tv/top_rated?api_key=$apiKey®ion=US" to "Top Rated TV Shows",
|
||||||
"$tmdbAPI/movie/upcoming?api_key=$apiKey®ion=US" to "Upcoming Movies",
|
"$tmdbAPI/movie/upcoming?api_key=$apiKey®ion=US" to "Upcoming Movies",
|
||||||
|
@ -355,7 +356,6 @@ open class SoraStream : TmdbProvider() {
|
||||||
res.season,
|
res.season,
|
||||||
res.episode,
|
res.episode,
|
||||||
subtitleCallback,
|
subtitleCallback,
|
||||||
callback,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@ import com.hexated.SoraExtractor.invokeRStream
|
||||||
import com.hexated.SoraExtractor.invokeSeries9
|
import com.hexated.SoraExtractor.invokeSeries9
|
||||||
import com.hexated.SoraExtractor.invokeSmashyStream
|
import com.hexated.SoraExtractor.invokeSmashyStream
|
||||||
import com.hexated.SoraExtractor.invokeSoraStream
|
import com.hexated.SoraExtractor.invokeSoraStream
|
||||||
|
import com.hexated.SoraExtractor.invokeSoraStreamLite
|
||||||
import com.hexated.SoraExtractor.invokeTwoEmbed
|
import com.hexated.SoraExtractor.invokeTwoEmbed
|
||||||
import com.hexated.SoraExtractor.invokeUniqueStream
|
import com.hexated.SoraExtractor.invokeUniqueStream
|
||||||
import com.hexated.SoraExtractor.invokeVidSrc
|
import com.hexated.SoraExtractor.invokeVidSrc
|
||||||
|
@ -53,7 +54,7 @@ class SoraStreamLite : SoraStream() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
invokeSoraStream(
|
invokeSoraStreamLite(
|
||||||
res.title,
|
res.title,
|
||||||
res.year,
|
res.year,
|
||||||
res.season,
|
res.season,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.hexated
|
package com.hexated
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
|
import com.hexated.SoraStream.Companion.base64DecodeAPI
|
||||||
import com.hexated.SoraStream.Companion.baymoviesAPI
|
import com.hexated.SoraStream.Companion.baymoviesAPI
|
||||||
import com.hexated.SoraStream.Companion.consumetCrunchyrollAPI
|
import com.hexated.SoraStream.Companion.consumetCrunchyrollAPI
|
||||||
import com.hexated.SoraStream.Companion.filmxyAPI
|
import com.hexated.SoraStream.Companion.filmxyAPI
|
||||||
|
@ -35,6 +36,15 @@ import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
|
val soraAPI = base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
|
||||||
|
|
||||||
|
val soraHeaders = mapOf(
|
||||||
|
"lang" to "en",
|
||||||
|
"versioncode" to "32",
|
||||||
|
"clienttype" to "android_tem3",
|
||||||
|
"deviceid" to getDeviceId(),
|
||||||
|
)
|
||||||
|
|
||||||
val encodedIndex = arrayOf(
|
val encodedIndex = arrayOf(
|
||||||
"GamMovies",
|
"GamMovies",
|
||||||
"JSMovies",
|
"JSMovies",
|
||||||
|
@ -67,6 +77,10 @@ val untrimmedIndex = arrayOf(
|
||||||
"EdithxMovies",
|
"EdithxMovies",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val needRefererIndex = arrayOf(
|
||||||
|
"ShinobiMovies",
|
||||||
|
)
|
||||||
|
|
||||||
val mimeType = arrayOf(
|
val mimeType = arrayOf(
|
||||||
"video/x-matroska",
|
"video/x-matroska",
|
||||||
"video/mp4",
|
"video/mp4",
|
||||||
|
@ -442,6 +456,56 @@ suspend fun invokeSmashyTwo(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getSoraIdAndType(title: String?, year: Int?, season: Int?) : Pair<String, String>? {
|
||||||
|
val doc = app.get("${base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")}/search?keyword=$title").document
|
||||||
|
val scriptData = doc.select("div.search-list div.search-video-card").map {
|
||||||
|
Triple(
|
||||||
|
it.selectFirst("h2.title")?.text().toString(),
|
||||||
|
it.selectFirst("div.desc")?.text()
|
||||||
|
?.substringBefore(".")?.toIntOrNull(),
|
||||||
|
it.selectFirst("a")?.attr("href")?.split("/")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val script = if (scriptData.size == 1) {
|
||||||
|
scriptData.firstOrNull()
|
||||||
|
} else {
|
||||||
|
scriptData.find {
|
||||||
|
when (season) {
|
||||||
|
null -> {
|
||||||
|
it.first.equals(
|
||||||
|
title,
|
||||||
|
true
|
||||||
|
) && it.second == year
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
it.first.contains(
|
||||||
|
"$title",
|
||||||
|
true
|
||||||
|
) && (it.second == year || it.first.contains("Season $season", true))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
it.first.contains(Regex("(?i)$title\\s?($season|${season.toRomanNumeral()}|Season\\s$season)")) && it.second == year
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val id = script?.third?.last() ?: return null
|
||||||
|
val type = script.third?.get(2) ?: return null
|
||||||
|
|
||||||
|
return id to type
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchSoraEpisodes(id: String, type: String, episode: Int?) : EpisodeVo? {
|
||||||
|
return app.get(
|
||||||
|
"$soraAPI/movieDrama/get?id=${id}&category=${type}",
|
||||||
|
headers = soraHeaders
|
||||||
|
).parsedSafe<Load>()?.data?.episodeVo?.find {
|
||||||
|
it.seriesNo == (episode ?: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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@{
|
||||||
|
@ -832,6 +896,16 @@ fun getGMoviesQuality(str: String): Int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSoraQuality(quality: String): Int {
|
||||||
|
return when (quality) {
|
||||||
|
"GROOT_FD" -> Qualities.P360.value
|
||||||
|
"GROOT_LD" -> Qualities.P480.value
|
||||||
|
"GROOT_SD" -> Qualities.P720.value
|
||||||
|
"GROOT_HD" -> Qualities.P1080.value
|
||||||
|
else -> Qualities.Unknown.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getFDoviesQuality(str: String): String {
|
fun getFDoviesQuality(str: String): String {
|
||||||
return when {
|
return when {
|
||||||
str.contains("1080P", true) -> "1080P"
|
str.contains("1080P", true) -> "1080P"
|
||||||
|
@ -858,6 +932,13 @@ fun getDbgoLanguage(str: String): String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDeviceId(length: Int = 16): String {
|
||||||
|
val allowedChars = ('a'..'f') + ('0'..'9')
|
||||||
|
return (1..length)
|
||||||
|
.map { allowedChars.random() }
|
||||||
|
.joinToString("")
|
||||||
|
}
|
||||||
|
|
||||||
fun String.encodeUrl(): String {
|
fun String.encodeUrl(): String {
|
||||||
val url = URL(this)
|
val url = URL(this)
|
||||||
val uri = URI(url.protocol, url.userInfo, url.host, url.port, url.path, url.query, url.ref)
|
val uri = URI(url.protocol, url.userInfo, url.host, url.port, url.path, url.query, url.ref)
|
||||||
|
|
Loading…
Reference in a new issue