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…
	
	Add table
		Add a link
		
	
		Reference in a new issue