mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
fix few providers
This commit is contained in:
parent
c13ed67d60
commit
20dbd2a774
9 changed files with 28 additions and 165 deletions
|
@ -1,115 +0,0 @@
|
||||||
package com.hexated
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
|
||||||
import com.lagradost.cloudstream3.*
|
|
||||||
import com.lagradost.cloudstream3.extractors.DoodLaExtractor
|
|
||||||
import com.lagradost.cloudstream3.extractors.Filesim
|
|
||||||
import com.lagradost.cloudstream3.extractors.StreamSB
|
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils
|
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
|
||||||
import java.net.URI
|
|
||||||
import javax.crypto.Cipher
|
|
||||||
import javax.crypto.SecretKeyFactory
|
|
||||||
import javax.crypto.spec.IvParameterSpec
|
|
||||||
import javax.crypto.spec.PBEKeySpec
|
|
||||||
import javax.crypto.spec.SecretKeySpec
|
|
||||||
|
|
||||||
object LocalServer {
|
|
||||||
private const val KEY = "4VqE3#N7zt&HEP^a"
|
|
||||||
|
|
||||||
private fun getBaseUrl(url: String): String {
|
|
||||||
return URI(url).let {
|
|
||||||
"${it.scheme}://${it.host}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getUrl(
|
|
||||||
url: String,
|
|
||||||
referer: String?,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit
|
|
||||||
) {
|
|
||||||
val mainUrl = getBaseUrl(url)
|
|
||||||
val master = Regex("MasterJS\\s*=\\s*'([^']+)").find(
|
|
||||||
app.get(
|
|
||||||
url,
|
|
||||||
referer = referer
|
|
||||||
).text
|
|
||||||
)?.groupValues?.get(1)
|
|
||||||
val encData = AppUtils.tryParseJson<AESData>(base64Decode(master ?: return))
|
|
||||||
val decrypt = cryptoAESHandler(encData ?: return, KEY, false)
|
|
||||||
|
|
||||||
val source = Regex(""""?file"?:\s*"([^"]+)""").find(decrypt)?.groupValues?.get(1)
|
|
||||||
|
|
||||||
// required
|
|
||||||
val headers = mapOf(
|
|
||||||
"Accept" to "*/*",
|
|
||||||
"Connection" to "keep-alive",
|
|
||||||
"Sec-Fetch-Dest" to "empty",
|
|
||||||
"Sec-Fetch-Mode" to "cors",
|
|
||||||
"Sec-Fetch-Site" to "cross-site",
|
|
||||||
"Origin" to mainUrl,
|
|
||||||
)
|
|
||||||
|
|
||||||
callback.invoke(
|
|
||||||
ExtractorLink(
|
|
||||||
Ngefilm().name,
|
|
||||||
Ngefilm().name,
|
|
||||||
source ?: return,
|
|
||||||
"$mainUrl/",
|
|
||||||
Qualities.P1080.value,
|
|
||||||
headers = headers,
|
|
||||||
isM3u8 = true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun cryptoAESHandler(
|
|
||||||
data: AESData,
|
|
||||||
pass: String,
|
|
||||||
encrypt: Boolean = true
|
|
||||||
): String {
|
|
||||||
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512")
|
|
||||||
val spec = PBEKeySpec(
|
|
||||||
pass.toCharArray(),
|
|
||||||
data.salt?.hexToByteArray(),
|
|
||||||
data.iterations?.toIntOrNull() ?: 1,
|
|
||||||
256
|
|
||||||
)
|
|
||||||
val key = factory.generateSecret(spec)
|
|
||||||
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
|
||||||
return if (!encrypt) {
|
|
||||||
cipher.init(
|
|
||||||
Cipher.DECRYPT_MODE,
|
|
||||||
SecretKeySpec(key.encoded, "AES"),
|
|
||||||
IvParameterSpec(data.iv?.hexToByteArray())
|
|
||||||
)
|
|
||||||
String(cipher.doFinal(base64DecodeArray(data.ciphertext.toString())))
|
|
||||||
} else {
|
|
||||||
cipher.init(
|
|
||||||
Cipher.ENCRYPT_MODE,
|
|
||||||
SecretKeySpec(key.encoded, "AES"),
|
|
||||||
IvParameterSpec(data.iv?.hexToByteArray())
|
|
||||||
)
|
|
||||||
base64Encode(cipher.doFinal(data.ciphertext?.toByteArray()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.hexToByteArray(): ByteArray {
|
|
||||||
check(length % 2 == 0) { "Must have an even length" }
|
|
||||||
return chunked(2)
|
|
||||||
.map { it.toInt(16).toByte() }
|
|
||||||
|
|
||||||
.toByteArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
data class AESData(
|
|
||||||
@JsonProperty("ciphertext") val ciphertext: String? = null,
|
|
||||||
@JsonProperty("iv") val iv: String? = null,
|
|
||||||
@JsonProperty("salt") val salt: String? = null,
|
|
||||||
@JsonProperty("iterations") val iterations: String? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,14 +19,6 @@ class Ngefilm : MainAPI() {
|
||||||
TvType.AsianDrama
|
TvType.AsianDrama
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val localServer = arrayOf(
|
|
||||||
"https://bestx.stream",
|
|
||||||
"https://chillx.top",
|
|
||||||
"https://watchx.top",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val mainPage = mainPageOf(
|
override val mainPage = mainPageOf(
|
||||||
"?s&search=advanced&post_type=movie&index&orderby&genre&movieyear&country&quality=" to "Movies Terbaru",
|
"?s&search=advanced&post_type=movie&index&orderby&genre&movieyear&country&quality=" to "Movies Terbaru",
|
||||||
"?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=&quality=" to "Series Terbaru",
|
"?s=&search=advanced&post_type=tv&index=&orderby=&genre=&movieyear=&country=&quality=" to "Series Terbaru",
|
||||||
|
@ -128,12 +120,8 @@ class Ngefilm : MainAPI() {
|
||||||
document.select("ul.muvipro-player-tabs li a").apmap { server ->
|
document.select("ul.muvipro-player-tabs li a").apmap { server ->
|
||||||
val iframe = app.get(fixUrl(server.attr("href"))).document.selectFirst("div.gmr-embed-responsive iframe")
|
val iframe = app.get(fixUrl(server.attr("href"))).document.selectFirst("div.gmr-embed-responsive iframe")
|
||||||
?.attr("src")?.let { fixUrl(it) } ?: return@apmap
|
?.attr("src")?.let { fixUrl(it) } ?: return@apmap
|
||||||
if (localServer.any { iframe.startsWith(it) }) {
|
|
||||||
LocalServer.getUrl(iframe, "$mainUrl/", subtitleCallback, callback)
|
|
||||||
} else {
|
|
||||||
loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback)
|
loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,5 @@ class NgefilmPlugin: Plugin() {
|
||||||
override fun load(context: Context) {
|
override fun load(context: Context) {
|
||||||
// All providers should be added in this manner. Please don't edit the providers list directly.
|
// All providers should be added in this manner. Please don't edit the providers list directly.
|
||||||
registerMainAPI(Ngefilm())
|
registerMainAPI(Ngefilm())
|
||||||
registerExtractorAPI(Sbsonic())
|
|
||||||
registerExtractorAPI(Sbface())
|
|
||||||
registerExtractorAPI(Sbrapid())
|
|
||||||
registerExtractorAPI(Lvturbo())
|
|
||||||
registerExtractorAPI(Ahvsh())
|
|
||||||
registerExtractorAPI(Guccihide())
|
|
||||||
registerExtractorAPI(Dooood())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,5 @@ class OploverzProviderPlugin: Plugin() {
|
||||||
override fun load(context: Context) {
|
override fun load(context: Context) {
|
||||||
// All providers should be added in this manner. Please don't edit the providers list directly.
|
// All providers should be added in this manner. Please don't edit the providers list directly.
|
||||||
registerMainAPI(OploverzProvider())
|
registerMainAPI(OploverzProvider())
|
||||||
registerExtractorAPI(Streamhide())
|
|
||||||
registerExtractorAPI(Pixeldrain())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 = 143
|
version = 144
|
||||||
|
|
||||||
android {
|
android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
|
|
@ -960,7 +960,7 @@ object SoraExtractor : SoraStream() {
|
||||||
) {
|
) {
|
||||||
val res = app.get(
|
val res = app.get(
|
||||||
"$biliBiliAPI/anime/episodes?id=${aniId ?: return}&source_id=bilibili",
|
"$biliBiliAPI/anime/episodes?id=${aniId ?: return}&source_id=bilibili",
|
||||||
referer = kaguyaBaseUrl
|
referer = otakuzBaseUrl
|
||||||
)
|
)
|
||||||
.parsedSafe<BiliBiliDetails>()?.episodes?.find {
|
.parsedSafe<BiliBiliDetails>()?.episodes?.find {
|
||||||
it.episodeNumber == episode
|
it.episodeNumber == episode
|
||||||
|
@ -969,7 +969,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val sources =
|
val sources =
|
||||||
app.get(
|
app.get(
|
||||||
"$biliBiliAPI/source?episode_id=${res.sourceEpisodeId}&source_media_id=${res.sourceMediaId}&source_id=${res.sourceId}",
|
"$biliBiliAPI/source?episode_id=${res.sourceEpisodeId}&source_media_id=${res.sourceMediaId}&source_id=${res.sourceId}",
|
||||||
referer = kaguyaBaseUrl
|
referer = otakuzBaseUrl
|
||||||
)
|
)
|
||||||
.parsedSafe<BiliBiliSourcesResponse>()
|
.parsedSafe<BiliBiliSourcesResponse>()
|
||||||
|
|
||||||
|
@ -977,7 +977,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val quality =
|
val quality =
|
||||||
app.get(
|
app.get(
|
||||||
source.file ?: return@apmap null,
|
source.file ?: return@apmap null,
|
||||||
referer = kaguyaBaseUrl
|
referer = otakuzBaseUrl
|
||||||
).document.selectFirst("Representation")
|
).document.selectFirst("Representation")
|
||||||
?.attr("height")
|
?.attr("height")
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
|
@ -985,7 +985,7 @@ object SoraExtractor : SoraStream() {
|
||||||
"BiliBili",
|
"BiliBili",
|
||||||
"BiliBili",
|
"BiliBili",
|
||||||
source.file,
|
source.file,
|
||||||
kaguyaBaseUrl,
|
"",
|
||||||
quality?.toIntOrNull() ?: Qualities.Unknown.value,
|
quality?.toIntOrNull() ?: Qualities.Unknown.value,
|
||||||
isDash = true
|
isDash = true
|
||||||
)
|
)
|
||||||
|
|
|
@ -121,7 +121,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
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=")
|
||||||
const val ask4MoviesAPI = "https://ask4movie.net"
|
const val ask4MoviesAPI = "https://ask4movie.net"
|
||||||
const val biliBiliAPI = "https://api-vn.kaguya.app/server"
|
const val biliBiliAPI = "https://api-vn.otakuz.live/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"
|
||||||
const val putlockerAPI = "https://ww7.putlocker.vip"
|
const val putlockerAPI = "https://ww7.putlocker.vip"
|
||||||
|
@ -500,16 +500,16 @@ open class SoraStream : TmdbProvider() {
|
||||||
{
|
{
|
||||||
if(!res.isAnime) invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback)
|
if(!res.isAnime) invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
invokeXmovies(
|
// invokeXmovies(
|
||||||
res.title,
|
// res.title,
|
||||||
res.year,
|
// res.year,
|
||||||
res.season,
|
// res.season,
|
||||||
res.episode,
|
// res.episode,
|
||||||
subtitleCallback,
|
// subtitleCallback,
|
||||||
callback
|
// callback
|
||||||
)
|
// )
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
if (!res.isAnime) invokeFmovies(
|
if (!res.isAnime) invokeFmovies(
|
||||||
res.title,
|
res.title,
|
||||||
|
|
|
@ -200,16 +200,16 @@ class SoraStreamLite : SoraStream() {
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
invokeXmovies(
|
// invokeXmovies(
|
||||||
res.title,
|
// res.title,
|
||||||
res.year,
|
// res.year,
|
||||||
res.season,
|
// res.season,
|
||||||
res.episode,
|
// res.episode,
|
||||||
subtitleCallback,
|
// subtitleCallback,
|
||||||
callback
|
// callback
|
||||||
)
|
// )
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
if (!res.isAnime) invokeFmovies(
|
if (!res.isAnime) invokeFmovies(
|
||||||
res.title,
|
res.title,
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.hexated
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.hexated.DumpUtils.createHeaders
|
|
||||||
import com.hexated.DumpUtils.queryApi
|
import com.hexated.DumpUtils.queryApi
|
||||||
import com.hexated.SoraStream.Companion.anilistAPI
|
import com.hexated.SoraStream.Companion.anilistAPI
|
||||||
import com.hexated.SoraStream.Companion.base64DecodeAPI
|
import com.hexated.SoraStream.Companion.base64DecodeAPI
|
||||||
|
@ -51,7 +50,7 @@ import kotlin.math.min
|
||||||
|
|
||||||
val bflixChipperKey = base64DecodeAPI("Yjc=ejM=TzA=YTk=WHE=WnU=bXU=RFo=")
|
val bflixChipperKey = base64DecodeAPI("Yjc=ejM=TzA=YTk=WHE=WnU=bXU=RFo=")
|
||||||
const val bflixKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
const val bflixKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||||
const val kaguyaBaseUrl = "https://kaguya.app/"
|
const val otakuzBaseUrl = "https://otakuz.live/"
|
||||||
val soraHeaders = mapOf(
|
val soraHeaders = mapOf(
|
||||||
"lang" to "en",
|
"lang" to "en",
|
||||||
"versioncode" to "33",
|
"versioncode" to "33",
|
||||||
|
|
Loading…
Reference in a new issue