diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index 13d0e587..4b78022b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -2,6 +2,7 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.utils.* import org.jsoup.Jsoup @@ -27,18 +28,31 @@ class GogoanimeProvider : MainAPI() { } } + /** + * @param id base64Decode(show_id) + IV + * @return the encryption key + * */ + private fun getKey(id: String): String? { + return normalSafeApiCall { + id.map { + it.code.toString(16) + }.joinToString("").substring(0, 32) + } + } + val qualityRegex = Regex("(\\d+)P") // https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt#L60 // No Licence on the function private fun cryptoHandler( string: String, - iv: ByteArray, - secretKeyString: ByteArray, + iv: String, + secretKeyString: String, encrypt: Boolean = true ): String { - val ivParameterSpec = IvParameterSpec(iv) - val secretKey = SecretKeySpec(secretKeyString, "AES") + println("IV: $iv, Key: $secretKeyString, encrypt: $encrypt, Message: $string") + val ivParameterSpec = IvParameterSpec(iv.toByteArray()) + val secretKey = SecretKeySpec(secretKeyString.toByteArray(), "AES") val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") return if (!encrypt) { cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec) @@ -59,31 +73,41 @@ class GogoanimeProvider : MainAPI() { /** * @param iframeUrl something like https://gogoplay4.com/streaming.php?id=XXXXXX * @param mainApiName used for ExtractorLink names and source - * @param iv secret iv from site, required non-null - * @param secretKey secret key for decryption from site, required non-null - * @param secretDecryptKey secret key to decrypt the response json, required non-null + * @param iv secret iv 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 isUsingAdaptiveKeys generates keys from IV and ID, see getKey() * */ suspend fun extractVidstream( iframeUrl: String, mainApiName: String, callback: (ExtractorLink) -> Unit, - iv: ByteArray?, - secretKey: ByteArray?, - secretDecryptKey: ByteArray? + iv: String?, + secretKey: String?, + secretDecryptKey: String?, + // This could be removed, but i prefer it verbose + isUsingAdaptiveKeys: Boolean ) = safeApiCall { // 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 // Also modified of https://github.com/jmir1/aniyomi-extensions/blob/master/src/en/gogoanime/src/eu/kanade/tachiyomi/animeextension/en/gogoanime/extractors/GogoCdnExtractor.kt // License on the code above https://github.com/jmir1/aniyomi-extensions/blob/master/LICENSE - if (iv == null || secretKey == null || secretDecryptKey == null) + if ((iv == null || secretKey == null || secretDecryptKey == null) && !isUsingAdaptiveKeys) return@safeApiCall + val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=") + + val foundIv = + iv ?: app.get(iframeUrl).document.select("""div.wrapper[class*=container]""") + .attr("class").split("-").lastOrNull() ?: return@safeApiCall + val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return@safeApiCall + val foundDecryptKey = secretDecryptKey ?: foundKey + val uri = URI(iframeUrl) val mainUrl = "https://" + uri.host - val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=") - val encryptedId = cryptoHandler(id, iv, secretKey) + val encryptedId = cryptoHandler(id, foundIv, foundKey) val jsonResponse = app.get( "$mainUrl/encrypt-ajax.php?id=$encryptedId&alias=$id", @@ -91,7 +115,7 @@ class GogoanimeProvider : MainAPI() { ) val dataencrypted = jsonResponse.text.substringAfter("{\"data\":\"").substringBefore("\"}") - val datadecrypted = cryptoHandler(dataencrypted, iv, secretDecryptKey, false) + val datadecrypted = cryptoHandler(dataencrypted, foundIv, foundDecryptKey, false) val sources = AppUtils.parseJson(datadecrypted) fun invokeGogoSource( @@ -372,12 +396,18 @@ class GogoanimeProvider : MainAPI() { loadExtractor(data, streamingResponse.url, callback) } }, { - val iv = "8244002440089157".toByteArray() - val secretKey = - "93106165734640459728346589106791".toByteArray() - val secretDecryptKey = - "97952160493714852094564712118349".toByteArray() - extractVidstream(iframe, this.name, callback, iv, secretKey, secretDecryptKey) + val iv = null //"2094564712118349" + val secretKey = null + val secretDecryptKey = null + extractVidstream( + iframe, + this.name, + callback, + iv, + secretKey, + secretDecryptKey, + true + ) }) } ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsianLoadProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsianLoadProvider.kt index ef798be1..0d73f16e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsianLoadProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AsianLoadProvider.kt @@ -17,8 +17,8 @@ class AsianLoadProvider : VidstreamProviderTemplate() { "$mainUrl/ongoing-series" ) - override val iv = "9262859232435825".toByteArray() - override val secretKey = "93422192433952489752342908585752".toByteArray() + override val iv = "9262859232435825" + override val secretKey = "93422192433952489752342908585752" override val supportedTypes = setOf(TvType.AsianDrama) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt index 994b4915..127753a3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt @@ -197,9 +197,9 @@ class DramaSeeProvider : MainAPI() { //Log.i(this.name, "Result => (url) ${url}") when { url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { - val iv = "9262859232435825".toByteArray() - val secretKey = "93422192433952489752342908585752".toByteArray() - extractVidstream(url, this.name, callback, iv, secretKey, secretKey) + val iv = "9262859232435825" + val secretKey = "93422192433952489752342908585752" + extractVidstream(url, this.name, callback, iv, secretKey, secretKey, false) AsianEmbedHelper.getUrls(url, callback) } url.startsWith("https://embedsito.com") -> { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt index 4ecbeaca..d72a4d9f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt @@ -20,8 +20,9 @@ class VidEmbedProvider : VidstreamProviderTemplate() { "$mainUrl/cinema-movies" ) - override val iv = "9225679083961858".toByteArray() - override val secretKey = "25742532592138496744665879883281".toByteArray() + override val iv = "9225679083961858" + override val secretKey = "25742532592138496744665879883281" + override val secretDecryptKey = secretKey // This is just extra metadata about what type of movies the provider has. // Needed for search functionality. diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt index 866ad4e6..a344ee37 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt @@ -64,9 +64,12 @@ open class VidstreamProviderTemplate : MainAPI() { */ */ - open val iv: ByteArray? = null - open val secretKey: ByteArray? = null - open val secretDecryptKey: ByteArray? = null + open val iv: String? = null + open val secretKey: String? = null + open val secretDecryptKey: String? = null + /** Generated the key from IV and ID */ + open val isUsingAdaptiveKeys: Boolean = false + // // mainUrl is good to have as a holder for the url to make future changes easier. // override val mainUrl: String @@ -252,7 +255,7 @@ open class VidstreamProviderTemplate : MainAPI() { val iframeLink = Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false - extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey) + extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey, isUsingAdaptiveKeys) // 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. val vidstreamObject = Vidstream(vidstreamExtractorUrl ?: mainUrl) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt index f9791473..a2153914 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt @@ -214,9 +214,9 @@ class WatchAsianProvider : MainAPI() { //Log.i(this.name, "Result => (url) $url") when { url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { - val iv = "9262859232435825".toByteArray() - val secretKey = "93422192433952489752342908585752".toByteArray() - extractVidstream(url, this.name, callback, iv, secretKey, secretKey) + val iv = "9262859232435825" + val secretKey = "93422192433952489752342908585752" + extractVidstream(url, this.name, callback, iv, secretKey, secretKey, false) AsianEmbedHelper.getUrls(url, callback) } url.startsWith("https://embedsito.com") -> {