mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Updated VidSrc encryption methods (#1205)
This commit is contained in:
parent
4c7379c766
commit
0c418fdf9b
1 changed files with 227 additions and 74 deletions
|
@ -3,98 +3,251 @@ package com.lagradost.cloudstream3.extractors
|
||||||
import com.lagradost.cloudstream3.SubtitleFile
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
import com.lagradost.cloudstream3.amap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import kotlinx.coroutines.delay
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import java.net.URI
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
import java.util.Base64
|
||||||
|
|
||||||
class VidSrcExtractor2 : VidSrcExtractor() {
|
class VidSrcExtractor2 : VidSrcExtractor() {
|
||||||
override val mainUrl = "https://vidsrc.me/embed"
|
override val mainUrl = "https://vidsrc.me"
|
||||||
override suspend fun getUrl(
|
|
||||||
url: String,
|
|
||||||
referer: String?,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit
|
|
||||||
) {
|
|
||||||
val newUrl = url.lowercase().replace(mainUrl, super.mainUrl)
|
|
||||||
super.getUrl(newUrl, referer, subtitleCallback, callback)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open class VidSrcExtractor : ExtractorApi() {
|
open class VidSrcExtractor : ExtractorApi() {
|
||||||
override val name = "VidSrc"
|
override val name = "VidSrc"
|
||||||
private val absoluteUrl = "https://v2.vidsrc.me"
|
override val mainUrl = "https://vidsrc.net"
|
||||||
override val mainUrl = "$absoluteUrl/embed"
|
private val apiUrl = "https://vidsrc.stream"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
companion object {
|
|
||||||
/** Infinite function to validate the vidSrc pass */
|
|
||||||
suspend fun validatePass(url: String) {
|
|
||||||
val uri = URI(url)
|
|
||||||
val host = uri.host
|
|
||||||
|
|
||||||
// Basically turn https://tm3p.vidsrc.stream/ -> https://vidsrc.stream/
|
|
||||||
val referer = host.split(".").let {
|
|
||||||
val size = it.size
|
|
||||||
"https://" + it.subList(maxOf(0, size - 2), size).joinToString(".") + "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
app.get(url, referer = referer)
|
|
||||||
delay(60_000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getUrl(
|
override suspend fun getUrl(
|
||||||
url: String,
|
url: String,
|
||||||
referer: String?,
|
referer: String?,
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val iframedoc = app.get(url).document
|
val iframedoc = app.get(url).document
|
||||||
|
|
||||||
val serverslist =
|
val srcrcpList =
|
||||||
iframedoc.select("div#sources.button_content div#content div#list div").map {
|
iframedoc.select("div.serversList > div.server").mapNotNull {
|
||||||
val datahash = it.attr("data-hash")
|
val datahash = it.attr("data-hash") ?: return@mapNotNull null
|
||||||
if (datahash.isNotBlank()) {
|
val rcpLink = "$apiUrl/rcp/$datahash"
|
||||||
val links = try {
|
val rcpRes = app.get(rcpLink, referer = apiUrl).text
|
||||||
app.get(
|
val srcrcpLink =
|
||||||
"$absoluteUrl/srcrcp/$datahash",
|
Regex("src:\\s*'(.*)',").find(rcpRes)?.destructured?.component1()
|
||||||
referer = "https://rcp.vidsrc.me/"
|
?: return@mapNotNull null
|
||||||
).url
|
"https:$srcrcpLink"
|
||||||
} catch (e: Exception) {
|
}
|
||||||
""
|
|
||||||
}
|
|
||||||
links
|
|
||||||
} else ""
|
|
||||||
}
|
|
||||||
|
|
||||||
serverslist.amap { server ->
|
srcrcpList.amap { server ->
|
||||||
val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/")
|
val res = app.get(server, referer = apiUrl)
|
||||||
if (linkfixed.contains("/prorcp")) {
|
if (res.url.contains("/prorcp")) {
|
||||||
val srcresponse = app.get(server, referer = absoluteUrl).text
|
val encodedElement = res.document.select("div#reporting_content+div")
|
||||||
val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)")
|
val decodedUrl =
|
||||||
val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@amap
|
decodeUrl(encodedElement.attr("id"), encodedElement.text()) ?: return@amap
|
||||||
val passRegex = Regex("""['"](.*set_pass[^"']*)""")
|
|
||||||
val pass = passRegex.find(srcresponse)?.groupValues?.get(1)?.replace(
|
|
||||||
Regex("""^//"""), "https://"
|
|
||||||
)
|
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
this.name,
|
this.name,
|
||||||
this.name,
|
this.name,
|
||||||
srcm3u8,
|
decodedUrl,
|
||||||
"https://vidsrc.stream/",
|
apiUrl,
|
||||||
Qualities.Unknown.value,
|
Qualities.Unknown.value,
|
||||||
extractorData = pass,
|
isM3u8 = true
|
||||||
isM3u8 = true
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
loadExtractor(linkfixed, url, subtitleCallback, callback)
|
loadExtractor(res.url, url, subtitleCallback, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun decodeUrl(encType: String, url: String): String? {
|
||||||
|
return when (encType) {
|
||||||
|
"NdonQLf1Tzyx7bMG" -> bMGyx71TzQLfdonN(url)
|
||||||
|
"sXnL9MQIry" -> Iry9MQXnLs(url)
|
||||||
|
"IhWrImMIGL" -> IGLImMhWrI(url)
|
||||||
|
"xTyBxQyGTA" -> GTAxQyTyBx(url)
|
||||||
|
"ux8qjPHC66" -> C66jPHx8qu(url)
|
||||||
|
"eSfH1IRMyL" -> MyL1IRSfHe(url)
|
||||||
|
"KJHidj7det" -> detdj7JHiK(url)
|
||||||
|
"o2VSUnjnZl" -> nZlUnj2VSo(url)
|
||||||
|
"Oi3v1dAlaM" -> laM1dAi3vO(url)
|
||||||
|
"TsA2KGDGux" -> GuxKGDsA2T(url)
|
||||||
|
"JoAHUMCLXV" -> LXVUMCoAHJ(url)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bMGyx71TzQLfdonN(a: String): String {
|
||||||
|
val b = 3
|
||||||
|
val c = mutableListOf<String>()
|
||||||
|
var d = 0
|
||||||
|
while (d < a.length) {
|
||||||
|
c.add(a.substring(d, minOf(d + b, a.length)))
|
||||||
|
d += b
|
||||||
|
}
|
||||||
|
val e = c.reversed().joinToString("")
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Iry9MQXnLs(a: String): String {
|
||||||
|
val b = "pWB9V)[*4I`nJpp?ozyB~dbr9yt!_n4u"
|
||||||
|
val d = a.chunked(2).map { it.toInt(16).toChar() }.joinToString("")
|
||||||
|
var c = ""
|
||||||
|
for (e in d.indices) {
|
||||||
|
c += (d[e].code xor b[e % b.length].code).toChar()
|
||||||
|
}
|
||||||
|
var e = ""
|
||||||
|
for (ch in c) {
|
||||||
|
e += (ch.code - 3).toChar()
|
||||||
|
}
|
||||||
|
return String(Base64.getDecoder().decode(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IGLImMhWrI(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c =
|
||||||
|
b
|
||||||
|
.map {
|
||||||
|
when (it) {
|
||||||
|
in 'a'..'m', in 'A'..'M' -> it + 13
|
||||||
|
in 'n'..'z', in 'N'..'Z' -> it - 13
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.joinToString("")
|
||||||
|
val d = c.reversed()
|
||||||
|
return String(Base64.getDecoder().decode(d))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun GTAxQyTyBx(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c = b.filterIndexed { index, _ -> index % 2 == 0 }
|
||||||
|
return String(Base64.getDecoder().decode(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun C66jPHx8qu(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c = "X9a(O;FMV2-7VO5x;Ao:dN1NoFs?j,"
|
||||||
|
val d = b.chunked(2).map { it.toInt(16).toChar() }.joinToString("")
|
||||||
|
var e = ""
|
||||||
|
for (i in d.indices) {
|
||||||
|
e += (d[i].code xor c[i % c.length].code).toChar()
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MyL1IRSfHe(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c = b.map { (it.code - 1).toChar() }.joinToString("")
|
||||||
|
val d = c.chunked(2).map { it.toInt(16).toChar() }.joinToString("")
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun detdj7JHiK(a: String): String {
|
||||||
|
val b = a.substring(10, a.length - 16)
|
||||||
|
val c = "3SAY~#%Y(V%>5d/Yg\"\$G[Lh1rK4a;7ok"
|
||||||
|
val d = String(Base64.getDecoder().decode(b))
|
||||||
|
val e = c.repeat((d.length + c.length - 1) / c.length).substring(0, d.length)
|
||||||
|
var f = ""
|
||||||
|
for (i in d.indices) {
|
||||||
|
f += (d[i].code xor e[i].code).toChar()
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nZlUnj2VSo(a: String): String {
|
||||||
|
val b =
|
||||||
|
mapOf(
|
||||||
|
'x' to 'a',
|
||||||
|
'y' to 'b',
|
||||||
|
'z' to 'c',
|
||||||
|
'a' to 'd',
|
||||||
|
'b' to 'e',
|
||||||
|
'c' to 'f',
|
||||||
|
'd' to 'g',
|
||||||
|
'e' to 'h',
|
||||||
|
'f' to 'i',
|
||||||
|
'g' to 'j',
|
||||||
|
'h' to 'k',
|
||||||
|
'i' to 'l',
|
||||||
|
'j' to 'm',
|
||||||
|
'k' to 'n',
|
||||||
|
'l' to 'o',
|
||||||
|
'm' to 'p',
|
||||||
|
'n' to 'q',
|
||||||
|
'o' to 'r',
|
||||||
|
'p' to 's',
|
||||||
|
'q' to 't',
|
||||||
|
'r' to 'u',
|
||||||
|
's' to 'v',
|
||||||
|
't' to 'w',
|
||||||
|
'u' to 'x',
|
||||||
|
'v' to 'y',
|
||||||
|
'w' to 'z',
|
||||||
|
'X' to 'A',
|
||||||
|
'Y' to 'B',
|
||||||
|
'Z' to 'C',
|
||||||
|
'A' to 'D',
|
||||||
|
'B' to 'E',
|
||||||
|
'C' to 'F',
|
||||||
|
'D' to 'G',
|
||||||
|
'E' to 'H',
|
||||||
|
'F' to 'I',
|
||||||
|
'G' to 'J',
|
||||||
|
'H' to 'K',
|
||||||
|
'I' to 'L',
|
||||||
|
'J' to 'M',
|
||||||
|
'K' to 'N',
|
||||||
|
'L' to 'O',
|
||||||
|
'M' to 'P',
|
||||||
|
'N' to 'Q',
|
||||||
|
'O' to 'R',
|
||||||
|
'P' to 'S',
|
||||||
|
'Q' to 'T',
|
||||||
|
'R' to 'U',
|
||||||
|
'S' to 'V',
|
||||||
|
'T' to 'W',
|
||||||
|
'U' to 'X',
|
||||||
|
'V' to 'Y',
|
||||||
|
'W' to 'Z'
|
||||||
|
)
|
||||||
|
return a.map { b[it] ?: it }.joinToString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun laM1dAi3vO(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c = b.replace("-", "+").replace("_", "/")
|
||||||
|
val d = String(Base64.getDecoder().decode(c))
|
||||||
|
var e = ""
|
||||||
|
val f = 5
|
||||||
|
for (ch in d) {
|
||||||
|
e += (ch.code - f).toChar()
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun GuxKGDsA2T(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c = b.replace("-", "+").replace("_", "/")
|
||||||
|
val d = String(Base64.getDecoder().decode(c))
|
||||||
|
var e = ""
|
||||||
|
val f = 7
|
||||||
|
for (ch in d) {
|
||||||
|
e += (ch.code - f).toChar()
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun LXVUMCoAHJ(a: String): String {
|
||||||
|
val b = a.reversed()
|
||||||
|
val c = b.replace("-", "+").replace("_", "/")
|
||||||
|
val d = String(Base64.getDecoder().decode(c))
|
||||||
|
var e = ""
|
||||||
|
val f = 3
|
||||||
|
for (ch in d) {
|
||||||
|
e += (ch.code - f).toChar()
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue