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
|
||||
)
|
||||
|
||||
companion object {
|
||||
private val localServer = arrayOf(
|
||||
"https://bestx.stream",
|
||||
"https://chillx.top",
|
||||
"https://watchx.top",
|
||||
)
|
||||
}
|
||||
|
||||
override val mainPage = mainPageOf(
|
||||
"?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",
|
||||
|
@ -128,12 +120,8 @@ class Ngefilm : MainAPI() {
|
|||
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")
|
||||
?.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)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
|
|
|
@ -10,12 +10,5 @@ class NgefilmPlugin: Plugin() {
|
|||
override fun load(context: Context) {
|
||||
// All providers should be added in this manner. Please don't edit the providers list directly.
|
||||
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) {
|
||||
// All providers should be added in this manner. Please don't edit the providers list directly.
|
||||
registerMainAPI(OploverzProvider())
|
||||
registerExtractorAPI(Streamhide())
|
||||
registerExtractorAPI(Pixeldrain())
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
|
||||
// use an integer for version numbers
|
||||
version = 143
|
||||
version = 144
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
|
|
|
@ -960,7 +960,7 @@ object SoraExtractor : SoraStream() {
|
|||
) {
|
||||
val res = app.get(
|
||||
"$biliBiliAPI/anime/episodes?id=${aniId ?: return}&source_id=bilibili",
|
||||
referer = kaguyaBaseUrl
|
||||
referer = otakuzBaseUrl
|
||||
)
|
||||
.parsedSafe<BiliBiliDetails>()?.episodes?.find {
|
||||
it.episodeNumber == episode
|
||||
|
@ -969,7 +969,7 @@ object SoraExtractor : SoraStream() {
|
|||
val sources =
|
||||
app.get(
|
||||
"$biliBiliAPI/source?episode_id=${res.sourceEpisodeId}&source_media_id=${res.sourceMediaId}&source_id=${res.sourceId}",
|
||||
referer = kaguyaBaseUrl
|
||||
referer = otakuzBaseUrl
|
||||
)
|
||||
.parsedSafe<BiliBiliSourcesResponse>()
|
||||
|
||||
|
@ -977,7 +977,7 @@ object SoraExtractor : SoraStream() {
|
|||
val quality =
|
||||
app.get(
|
||||
source.file ?: return@apmap null,
|
||||
referer = kaguyaBaseUrl
|
||||
referer = otakuzBaseUrl
|
||||
).document.selectFirst("Representation")
|
||||
?.attr("height")
|
||||
callback.invoke(
|
||||
|
@ -985,7 +985,7 @@ object SoraExtractor : SoraStream() {
|
|||
"BiliBili",
|
||||
"BiliBili",
|
||||
source.file,
|
||||
kaguyaBaseUrl,
|
||||
"",
|
||||
quality?.toIntOrNull() ?: Qualities.Unknown.value,
|
||||
isDash = true
|
||||
)
|
||||
|
|
|
@ -121,7 +121,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.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 nineTvAPI = "https://api.9animetv.live"
|
||||
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)
|
||||
},
|
||||
{
|
||||
invokeXmovies(
|
||||
res.title,
|
||||
res.year,
|
||||
res.season,
|
||||
res.episode,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
// {
|
||||
// invokeXmovies(
|
||||
// res.title,
|
||||
// res.year,
|
||||
// res.season,
|
||||
// res.episode,
|
||||
// subtitleCallback,
|
||||
// callback
|
||||
// )
|
||||
// },
|
||||
{
|
||||
if (!res.isAnime) invokeFmovies(
|
||||
res.title,
|
||||
|
|
|
@ -200,16 +200,16 @@ class SoraStreamLite : SoraStream() {
|
|||
callback
|
||||
)
|
||||
},
|
||||
{
|
||||
invokeXmovies(
|
||||
res.title,
|
||||
res.year,
|
||||
res.season,
|
||||
res.episode,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
// {
|
||||
// invokeXmovies(
|
||||
// res.title,
|
||||
// res.year,
|
||||
// res.season,
|
||||
// res.episode,
|
||||
// subtitleCallback,
|
||||
// callback
|
||||
// )
|
||||
// },
|
||||
{
|
||||
if (!res.isAnime) invokeFmovies(
|
||||
res.title,
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.hexated
|
|||
|
||||
import android.util.Base64
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.hexated.DumpUtils.createHeaders
|
||||
import com.hexated.DumpUtils.queryApi
|
||||
import com.hexated.SoraStream.Companion.anilistAPI
|
||||
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=")
|
||||
const val bflixKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
const val kaguyaBaseUrl = "https://kaguya.app/"
|
||||
const val otakuzBaseUrl = "https://otakuz.live/"
|
||||
val soraHeaders = mapOf(
|
||||
"lang" to "en",
|
||||
"versioncode" to "33",
|
||||
|
|
Loading…
Reference in a new issue