mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
fixes on mcloud/vidstream/bflix/9anime (#1091)
* fixes * minor thing * minor thing
This commit is contained in:
parent
bf4bd7f5e2
commit
4fa60e6b5e
6 changed files with 111 additions and 43 deletions
|
@ -64,7 +64,7 @@ class NineAnimeProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Credits to https://github.com/jmir1
|
//Credits to https://github.com/jmir1
|
||||||
private val key = "0wMrYU+ixjJ4QdzgfN2HlyIVAt3sBOZnCT9Lm7uFDovkb/EaKpRWhqXS5168ePcG"
|
private val key = "c/aUAorINHBLxWTy3uRiPt8J+vjsOheFG1E0q2X9CYwDZlnmd4Kb5M6gSVzfk7pQ" //key credits to @Modder4869
|
||||||
|
|
||||||
private fun getVrf(id: String): String? {
|
private fun getVrf(id: String): String? {
|
||||||
val reversed = ue(encode(id) + "0000000").slice(0..5).reversed()
|
val reversed = ue(encode(id) + "0000000").slice(0..5).reversed()
|
||||||
|
|
|
@ -4,10 +4,12 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.USER_AGENT
|
import com.lagradost.cloudstream3.USER_AGENT
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.apmap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
|
import com.lagradost.cloudstream3.extractors.WcoStream.Companion.cipher
|
||||||
|
import com.lagradost.cloudstream3.extractors.WcoStream.Companion.encrypt
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
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
|
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
|
||||||
|
|
||||||
open class Mcloud : ExtractorApi() {
|
open class Mcloud : ExtractorApi() {
|
||||||
override var name = "Mcloud"
|
override var name = "Mcloud"
|
||||||
|
@ -27,42 +29,47 @@ open class Mcloud : ExtractorApi() {
|
||||||
"Referer" to "https://animekisa.in/", //Referer works for wco and animekisa, probably with others too
|
"Referer" to "https://animekisa.in/", //Referer works for wco and animekisa, probably with others too
|
||||||
"Pragma" to "no-cache",
|
"Pragma" to "no-cache",
|
||||||
"Cache-Control" to "no-cache",)
|
"Cache-Control" to "no-cache",)
|
||||||
|
private val key = "LCbu3iYC7ln24K7P" // key credits @Modder4869
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
val link = url.replace("$mainUrl/e/","$mainUrl/info/")
|
val id = url.substringAfter("e/").substringAfter("embed/").substringBefore("?")
|
||||||
|
val encryptedid = encrypt(cipher(key, encrypt(id))).replace("/", "_").replace("=","")
|
||||||
|
val link = "$mainUrl/info/$encryptedid"
|
||||||
val response = app.get(link, headers = headers).text
|
val response = app.get(link, headers = headers).text
|
||||||
|
|
||||||
if(response.startsWith("<!DOCTYPE html>")) {
|
if(response.startsWith("<!DOCTYPE html>")) {
|
||||||
// TODO decrypt html for link
|
// TODO decrypt html for link
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
data class SourcesMcloud (
|
||||||
data class Sources (
|
|
||||||
@JsonProperty("file" ) val file : String
|
@JsonProperty("file" ) val file : String
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Media (
|
data class MediaMcloud (
|
||||||
@JsonProperty("sources") val sources: List<Sources>
|
@JsonProperty("sources" ) val sources : ArrayList<SourcesMcloud> = arrayListOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DataMcloud (
|
||||||
|
@JsonProperty("media" ) val media : MediaMcloud? = MediaMcloud()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class JsonMcloud (
|
data class JsonMcloud (
|
||||||
@JsonProperty("success") val success: Boolean,
|
@JsonProperty("status" ) val status : Int? = null,
|
||||||
@JsonProperty("media") val media: Media,
|
@JsonProperty("data" ) val data : DataMcloud = DataMcloud()
|
||||||
)
|
)
|
||||||
|
|
||||||
val mapped = parseJson<JsonMcloud>(response)
|
val mapped = parseJson<JsonMcloud>(response)
|
||||||
val sources = mutableListOf<ExtractorLink>()
|
val sources = mutableListOf<ExtractorLink>()
|
||||||
|
val checkfile = mapped.status == 200
|
||||||
if (mapped.success)
|
if (checkfile)
|
||||||
mapped.media.sources.apmap {
|
mapped.data.media?.sources?.apmap {
|
||||||
if (it.file.contains("m3u8")) {
|
if (it.file.contains("m3u8")) {
|
||||||
M3u8Helper.generateM3u8(
|
sources.addAll(
|
||||||
|
generateM3u8(
|
||||||
name,
|
name,
|
||||||
it.file,
|
it.file,
|
||||||
url,
|
url,
|
||||||
headers = app.get(url).headers.toMap()
|
headers = mapOf("Referer" to url)
|
||||||
).forEach { link ->
|
)
|
||||||
sources.add(link)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sources
|
return sources
|
||||||
|
|
|
@ -45,43 +45,102 @@ class VizcloudDigital : WcoStream() {
|
||||||
override var mainUrl = "https://vizcloud.digital"
|
override var mainUrl = "https://vizcloud.digital"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class VizcloudCloud : WcoStream() {
|
||||||
|
override var mainUrl = "https://vizcloud.cloud"
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val keytwo = "0wMrYU+ixjJ4QdzgfN2HlyIVAt3sBOZnCT9Lm7uFDovkb/EaKpRWhqXS5168ePcG"
|
||||||
|
fun encrypt(input: String): String {
|
||||||
|
if (input.any { it.code >= 256 }) throw Exception("illegal characters!")
|
||||||
|
var output = ""
|
||||||
|
for (i in input.indices step 3) {
|
||||||
|
val a = intArrayOf(-1, -1, -1, -1)
|
||||||
|
a[0] = input[i].code shr 2
|
||||||
|
a[1] = (3 and input[i].code) shl 4
|
||||||
|
if (input.length > i + 1) {
|
||||||
|
a[1] = a[1] or (input[i + 1].code shr 4)
|
||||||
|
a[2] = (15 and input[i + 1].code) shl 2
|
||||||
|
}
|
||||||
|
if (input.length > i + 2) {
|
||||||
|
a[2] = a[2] or (input[i + 2].code shr 6)
|
||||||
|
a[3] = 63 and input[i + 2].code
|
||||||
|
}
|
||||||
|
for (n in a) {
|
||||||
|
if (n == -1) output += "="
|
||||||
|
else {
|
||||||
|
if (n in 0..63) output += keytwo[n]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cipher(inputOne: String, inputTwo: String): String {
|
||||||
|
val arr = IntArray(256) { it }
|
||||||
|
var output = ""
|
||||||
|
var u = 0
|
||||||
|
var r: Int
|
||||||
|
for (a in arr.indices) {
|
||||||
|
u = (u + arr[a] + inputOne[a % inputOne.length].code) % 256
|
||||||
|
r = arr[a]
|
||||||
|
arr[a] = arr[u]
|
||||||
|
arr[u] = r
|
||||||
|
}
|
||||||
|
u = 0
|
||||||
|
var c = 0
|
||||||
|
for (f in inputTwo.indices) {
|
||||||
|
c = (c + f) % 256
|
||||||
|
u = (u + arr[c]) % 256
|
||||||
|
r = arr[c]
|
||||||
|
arr[c] = arr[u]
|
||||||
|
arr[u] = r
|
||||||
|
output += (inputTwo[f].code xor arr[(arr[c] + arr[u]) % 256]).toChar()
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val key = "LCbu3iYC7ln24K7P" // key credits @Modder4869
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
val baseUrl = url.split("/e/")[0]
|
val baseUrl = url.split("/e/")[0]
|
||||||
|
|
||||||
val html = app.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
|
|
||||||
val (Id) = (Regex("/e/(.*?)?domain").find(url)?.destructured ?: Regex("""/e/(.*)""").find(
|
val (Id) = (Regex("/e/(.*?)?domain").find(url)?.destructured ?: Regex("""/e/(.*)""").find(
|
||||||
url
|
url
|
||||||
)?.destructured) ?: return emptyList()
|
)?.destructured) ?: return emptyList()
|
||||||
val (skey) = Regex("""skey\s=\s['"](.*?)['"];""").find(html)?.destructured
|
// val (skey) = Regex("""skey\s=\s['"](.*?)['"];""").find(html)?.destructured
|
||||||
?: return emptyList()
|
// ?: return emptyList()
|
||||||
|
|
||||||
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
|
val encryptedID = encrypt(cipher(key, encrypt(Id))).replace("/", "_").replace("=","")
|
||||||
|
val apiLink = "$baseUrl/info/$encryptedID"
|
||||||
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
||||||
|
|
||||||
data class Sources(
|
data class SourcesWco (
|
||||||
@JsonProperty("file") val file: String,
|
@JsonProperty("file" ) val file : String
|
||||||
@JsonProperty("label") val label: String?
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Media(
|
data class MediaWco (
|
||||||
@JsonProperty("sources") val sources: List<Sources>
|
@JsonProperty("sources" ) val sources : ArrayList<SourcesWco> = arrayListOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DataWco (
|
||||||
|
@JsonProperty("media" ) val media : MediaWco? = MediaWco()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class WcoResponse (
|
data class WcoResponse (
|
||||||
@JsonProperty("success") val success: Boolean,
|
@JsonProperty("status" ) val status : Int? = null,
|
||||||
@JsonProperty("media") val media: Media
|
@JsonProperty("data" ) val data : DataWco? = DataWco()
|
||||||
)
|
)
|
||||||
|
|
||||||
val mapped = app.get(apiLink, headers = mapOf("Referer" to referrer)).parsed<WcoResponse>()
|
val mapped = app.get(apiLink, headers = mapOf("Referer" to referrer)).parsed<WcoResponse>()
|
||||||
val sources = mutableListOf<ExtractorLink>()
|
val sources = mutableListOf<ExtractorLink>()
|
||||||
|
val check = mapped.status == 200
|
||||||
if (mapped.success) {
|
if (check) {
|
||||||
mapped.media.sources.forEach {
|
mapped.data?.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
|
||||||
|
@ -128,7 +187,8 @@ open class WcoStream : ExtractorApi() {
|
||||||
"https://vizcloud.live",
|
"https://vizcloud.live",
|
||||||
"https://vizcloud.info",
|
"https://vizcloud.info",
|
||||||
"https://mwvn.vizcloud.info",
|
"https://mwvn.vizcloud.info",
|
||||||
"https://vizcloud.digital"
|
"https://vizcloud.digital",
|
||||||
|
"https://vizcloud.cloud"
|
||||||
).contains(mainUrl)
|
).contains(mainUrl)
|
||||||
) {
|
) {
|
||||||
if (it.file.contains("m3u8")) {
|
if (it.file.contains("m3u8")) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ open class BflixProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Credits to https://github.com/jmir1
|
//Credits to https://github.com/jmir1
|
||||||
val key = "eST4kCjadnvlAm5b1BOGyLJzrE90Q6oKgRfhV+M8NDYtcxW3IP/qp2i7XHuwZFUs"
|
private val key = "5uLKesbh0nkrpPq9VwMC6+tQBdomjJ4HNl/fWOSiREvAYagT8yIG7zx2D13UZFXc" //key credits to @Modder4869
|
||||||
|
|
||||||
private fun getVrf(id: String): String? {
|
private fun getVrf(id: String): String? {
|
||||||
val reversed = ue(encode(id) + "0000000").slice(0..5).reversed()
|
val reversed = ue(encode(id) + "0000000").slice(0..5).reversed()
|
||||||
|
|
|
@ -117,6 +117,7 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
|
||||||
VizcloudInfo(),
|
VizcloudInfo(),
|
||||||
MwvnVizcloudInfo(),
|
MwvnVizcloudInfo(),
|
||||||
VizcloudDigital(),
|
VizcloudDigital(),
|
||||||
|
VizcloudCloud(),
|
||||||
Mp4Upload(),
|
Mp4Upload(),
|
||||||
StreamTape(),
|
StreamTape(),
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
"BflixProvider": {
|
"BflixProvider": {
|
||||||
"language": "en",
|
"language": "en",
|
||||||
"name": "Bflix",
|
"name": "Bflix",
|
||||||
"status": 0,
|
"status": 1,
|
||||||
"url": "https://bflix.ru"
|
"url": "https://bflix.ru"
|
||||||
},
|
},
|
||||||
"CinecalidadProvider": {
|
"CinecalidadProvider": {
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
"FmoviesToProvider": {
|
"FmoviesToProvider": {
|
||||||
"language": "en",
|
"language": "en",
|
||||||
"name": "Fmovies.to",
|
"name": "Fmovies.to",
|
||||||
"status": 0,
|
"status": 1,
|
||||||
"url": "https://fmovies.to"
|
"url": "https://fmovies.to"
|
||||||
},
|
},
|
||||||
"FrenchStreamProvider": {
|
"FrenchStreamProvider": {
|
||||||
|
@ -253,7 +253,7 @@
|
||||||
"NineAnimeProvider": {
|
"NineAnimeProvider": {
|
||||||
"language": "en",
|
"language": "en",
|
||||||
"name": "9Anime",
|
"name": "9Anime",
|
||||||
"status": 0,
|
"status": 1,
|
||||||
"url": "https://9anime.id"
|
"url": "https://9anime.id"
|
||||||
},
|
},
|
||||||
"NontonAnimeIDProvider": {
|
"NontonAnimeIDProvider": {
|
||||||
|
@ -331,7 +331,7 @@
|
||||||
"SflixProProvider": {
|
"SflixProProvider": {
|
||||||
"language": "en",
|
"language": "en",
|
||||||
"name": "Sflix.pro",
|
"name": "Sflix.pro",
|
||||||
"status": 0,
|
"status": 1,
|
||||||
"url": "https://sflix.pro"
|
"url": "https://sflix.pro"
|
||||||
},
|
},
|
||||||
"SflixProvider": {
|
"SflixProvider": {
|
||||||
|
|
Loading…
Reference in a new issue