Merge remote-tracking branch 'origin/master'

This commit is contained in:
LagradOst 2022-04-30 22:31:42 +02:00
commit 7294b21a9e
5 changed files with 60 additions and 28 deletions

View file

@ -6,6 +6,7 @@ import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.net.URI import java.net.URI
import java.util.* import java.util.*
import javax.crypto.Cipher import javax.crypto.Cipher
@ -34,7 +35,7 @@ class GogoanimeProvider : MainAPI() {
* */ * */
private fun getKey(id: String): String? { private fun getKey(id: String): String? {
return normalSafeApiCall { return normalSafeApiCall {
id.map { id.map {
it.code.toString(16) it.code.toString(16)
}.joinToString("").substring(0, 32) }.joinToString("").substring(0, 32)
} }
@ -77,6 +78,7 @@ class GogoanimeProvider : MainAPI() {
* @param secretKey secret key for decryption from site, required non-null if isUsingAdaptiveKeys is off * @param secretKey secret key for decryption from site, required non-null if isUsingAdaptiveKeys is off
* @param secretDecryptKey secret key to decrypt the response json, required non-null if isUsingAdaptiveKeys is off * @param secretDecryptKey secret key to decrypt the response json, required non-null if isUsingAdaptiveKeys is off
* @param isUsingAdaptiveKeys generates keys from IV and ID, see getKey() * @param isUsingAdaptiveKeys generates keys from IV and ID, see getKey()
* @param isUsingAdaptiveData generate encrypt-ajax data based on $("script[data-name='episode']")[0].dataset.value
* */ * */
suspend fun extractVidstream( suspend fun extractVidstream(
iframeUrl: String, iframeUrl: String,
@ -86,7 +88,8 @@ class GogoanimeProvider : MainAPI() {
secretKey: String?, secretKey: String?,
secretDecryptKey: String?, secretDecryptKey: String?,
// This could be removed, but i prefer it verbose // This could be removed, but i prefer it verbose
isUsingAdaptiveKeys: Boolean isUsingAdaptiveKeys: Boolean,
isUsingAdaptiveData: Boolean
) = safeApiCall { ) = safeApiCall {
// https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt // https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt
// No Licence on the following code // No Licence on the following code
@ -98,8 +101,10 @@ class GogoanimeProvider : MainAPI() {
val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=") val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=")
var document: Document? = null
val foundIv = val foundIv =
iv ?: app.get(iframeUrl).document.select("""div.wrapper[class*=container]""") iv ?: app.get(iframeUrl).document.also { document = it }
.select("""div.wrapper[class*=container]""")
.attr("class").split("-").lastOrNull() ?: return@safeApiCall .attr("class").split("-").lastOrNull() ?: return@safeApiCall
val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return@safeApiCall val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return@safeApiCall
val foundDecryptKey = secretDecryptKey ?: foundKey val foundDecryptKey = secretDecryptKey ?: foundKey
@ -108,9 +113,19 @@ class GogoanimeProvider : MainAPI() {
val mainUrl = "https://" + uri.host val mainUrl = "https://" + uri.host
val encryptedId = cryptoHandler(id, foundIv, foundKey) val encryptedId = cryptoHandler(id, foundIv, foundKey)
val encryptRequestData = if (isUsingAdaptiveData) {
// Only fetch the document if necessary
val realDocument = document ?: app.get(iframeUrl).document
val dataEncrypted = realDocument.select("script[data-name='episode']").attr("data-value")
val headers = cryptoHandler(dataEncrypted, foundIv, foundKey, false)
"id=$encryptedId&alias=$id&" + headers.substringAfter("&")
} else {
"id=$encryptedId&alias=$id"
}
val jsonResponse = val jsonResponse =
app.get( app.get(
"$mainUrl/encrypt-ajax.php?id=$encryptedId&alias=$id", "$mainUrl/encrypt-ajax.php?$encryptRequestData",
headers = mapOf("X-Requested-With" to "XMLHttpRequest") headers = mapOf("X-Requested-With" to "XMLHttpRequest")
) )
val dataencrypted = val dataencrypted =
@ -129,7 +144,7 @@ class GogoanimeProvider : MainAPI() {
source.file, source.file,
mainUrl, mainUrl,
headers = mapOf("Referer" to "https://gogoplay4.com") headers = mapOf("Referer" to "https://gogoplay4.com")
).forEach (sourceCallback) ).forEach(sourceCallback)
} }
source.file.contains("vidstreaming") -> { source.file.contains("vidstreaming") -> {
sourceCallback.invoke( sourceCallback.invoke(
@ -382,9 +397,9 @@ class GogoanimeProvider : MainAPI() {
loadExtractor(data, streamingResponse.url, callback) loadExtractor(data, streamingResponse.url, callback)
} }
}, { }, {
val iv = "4968442212618524" val iv = "3134003223491201"
val secretKey = "34541577475429958244002440089157" val secretKey = "37911490979715163134003223491201"
val secretDecryptKey = "20945647121183498244002440089157" val secretDecryptKey = "54674138327930866480207815084989"
extractVidstream( extractVidstream(
iframe, iframe,
this.name, this.name,
@ -392,7 +407,8 @@ class GogoanimeProvider : MainAPI() {
iv, iv,
secretKey, secretKey,
secretDecryptKey, secretDecryptKey,
false isUsingAdaptiveKeys = false,
isUsingAdaptiveData = true
) )
}) })
} }

View file

@ -1,10 +1,8 @@
package com.lagradost.cloudstream3.extractors package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.module.kotlin.readValue
import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mapper
import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
@ -48,7 +46,7 @@ class VizcloudDigital : WcoStream() {
} }
open class WcoStream : ExtractorApi() { open class WcoStream : ExtractorApi() {
override var name = "VidStream" //Cause works for animekisa and wco override var name = "VidStream" // Cause works for animekisa and wco
override var mainUrl = "https://vidstream.pro" override var mainUrl = "https://vidstream.pro"
override val requiresReferer = false override val requiresReferer = false
@ -65,8 +63,6 @@ open class WcoStream : ExtractorApi() {
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey" val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc" val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
val response = app.get(apiLink, headers = mapOf("Referer" to referrer)).text
data class Sources( data class Sources(
@JsonProperty("file") val file: String, @JsonProperty("file") val file: String,
@JsonProperty("label") val label: String? @JsonProperty("label") val label: String?
@ -81,14 +77,14 @@ open class WcoStream : ExtractorApi() {
@JsonProperty("media") val media: Media @JsonProperty("media") val media: Media
) )
val mapped = response.let { mapper.readValue<WcoResponse>(it) } val mapped = app.get(apiLink, headers = mapOf("Referer" to referrer)).mapped<WcoResponse>()
val sources = mutableListOf<ExtractorLink>() val sources = mutableListOf<ExtractorLink>()
if (mapped.success) { if (mapped.success) {
mapped.media.sources.forEach { mapped.media.sources.forEach {
if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") { if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") {
if (it.file.contains("vizcloud2.ru") || it.file.contains("vizcloud.online")) { if (it.file.contains("vizcloud2.ru") || it.file.contains("vizcloud.online")) {
//Had to do this thing 'cause "list.m3u8#.mp4" gives 404 error so no quality is added // Had to do this thing 'cause "list.m3u8#.mp4" gives 404 error so no quality is added
val link1080 = it.file.replace("list.m3u8#.mp4", "H4/v.m3u8") val link1080 = it.file.replace("list.m3u8#.mp4", "H4/v.m3u8")
val link720 = it.file.replace("list.m3u8#.mp4", "H3/v.m3u8") val link720 = it.file.replace("list.m3u8#.mp4", "H3/v.m3u8")
val link480 = it.file.replace("list.m3u8#.mp4", "H2/v.m3u8") val link480 = it.file.replace("list.m3u8#.mp4", "H2/v.m3u8")
@ -123,17 +119,26 @@ open class WcoStream : ExtractorApi() {
} }
} }
} }
} } else if (
if (mainUrl == "https://vidstream.pro" || mainUrl == "https://vidstreamz.online" || mainUrl == "https://vizcloud2.online" arrayOf(
|| mainUrl == "https://vizcloud.xyz" || mainUrl == "https://vizcloud.live" || mainUrl == "https://vizcloud.info" "https://vidstream.pro",
|| mainUrl == "https://mwvn.vizcloud.info" || mainUrl == "https://vizcloud.digital" "https://vidstreamz.online",
"https://vizcloud2.online",
"https://vizcloud.xyz",
"https://vizcloud.live",
"https://vizcloud.info",
"https://mwvn.vizcloud.info",
"https://vizcloud.digital"
).contains(mainUrl)
) { ) {
if (it.file.contains("m3u8")) { if (it.file.contains("m3u8")) {
generateM3u8( sources.addAll(
name, generateM3u8(
it.file.replace("#.mp4", ""), name,
url, it.file.replace("#.mp4", ""),
headers = mapOf("Referer" to url) url,
headers = mapOf("Referer" to url)
)
) )
} else { } else {
sources.add( sources.add(

View file

@ -199,7 +199,10 @@ class DramaSeeProvider : MainAPI() {
url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> {
val iv = "9262859232435825" val iv = "9262859232435825"
val secretKey = "93422192433952489752342908585752" val secretKey = "93422192433952489752342908585752"
extractVidstream(url, this.name, callback, iv, secretKey, secretKey, false) extractVidstream(url, this.name, callback, iv, secretKey, secretKey,
isUsingAdaptiveKeys = false,
isUsingAdaptiveData = false
)
AsianEmbedHelper.getUrls(url, callback) AsianEmbedHelper.getUrls(url, callback)
} }
url.startsWith("https://embedsito.com") -> { url.startsWith("https://embedsito.com") -> {

View file

@ -69,6 +69,11 @@ open class VidstreamProviderTemplate : MainAPI() {
open val secretDecryptKey: String? = null open val secretDecryptKey: String? = null
/** Generated the key from IV and ID */ /** Generated the key from IV and ID */
open val isUsingAdaptiveKeys: Boolean = false open val isUsingAdaptiveKeys: Boolean = false
/**
* Generate data for the encrypt-ajax automatically (only on supported sites)
* See $("script[data-name='episode']")[0].dataset.value
* */
open val isUsingAdaptiveData: Boolean = false
// // mainUrl is good to have as a holder for the url to make future changes easier. // // mainUrl is good to have as a holder for the url to make future changes easier.
@ -255,7 +260,7 @@ open class VidstreamProviderTemplate : MainAPI() {
val iframeLink = val iframeLink =
Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false
extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey, isUsingAdaptiveKeys) extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey, isUsingAdaptiveKeys, isUsingAdaptiveData)
// In this case the video player is a vidstream clone and can be handled by the vidstream extractor. // In this case the video player is a vidstream clone and can be handled by the vidstream extractor.
// This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest. // This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest.
val vidstreamObject = Vidstream(vidstreamExtractorUrl ?: mainUrl) val vidstreamObject = Vidstream(vidstreamExtractorUrl ?: mainUrl)

View file

@ -216,7 +216,10 @@ class WatchAsianProvider : MainAPI() {
url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> {
val iv = "9262859232435825" val iv = "9262859232435825"
val secretKey = "93422192433952489752342908585752" val secretKey = "93422192433952489752342908585752"
extractVidstream(url, this.name, callback, iv, secretKey, secretKey, false) extractVidstream(url, this.name, callback, iv, secretKey, secretKey,
isUsingAdaptiveKeys = false,
isUsingAdaptiveData = false
)
AsianEmbedHelper.getUrls(url, callback) AsianEmbedHelper.getUrls(url, callback)
} }
url.startsWith("https://embedsito.com") -> { url.startsWith("https://embedsito.com") -> {