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.amap
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
import kotlinx.coroutines.delay
|
||||
import java.net.URI
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
import java.util.Base64
|
||||
|
||||
class VidSrcExtractor2 : VidSrcExtractor() {
|
||||
override val mainUrl = "https://vidsrc.me/embed"
|
||||
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)
|
||||
}
|
||||
override val mainUrl = "https://vidsrc.me"
|
||||
}
|
||||
|
||||
open class VidSrcExtractor : ExtractorApi() {
|
||||
override val name = "VidSrc"
|
||||
private val absoluteUrl = "https://v2.vidsrc.me"
|
||||
override val mainUrl = "$absoluteUrl/embed"
|
||||
override val mainUrl = "https://vidsrc.net"
|
||||
private val apiUrl = "https://vidsrc.stream"
|
||||
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(
|
||||
url: String,
|
||||
referer: String?,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
url: String,
|
||||
referer: String?,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val iframedoc = app.get(url).document
|
||||
|
||||
val serverslist =
|
||||
iframedoc.select("div#sources.button_content div#content div#list div").map {
|
||||
val datahash = it.attr("data-hash")
|
||||
if (datahash.isNotBlank()) {
|
||||
val links = try {
|
||||
app.get(
|
||||
"$absoluteUrl/srcrcp/$datahash",
|
||||
referer = "https://rcp.vidsrc.me/"
|
||||
).url
|
||||
} catch (e: Exception) {
|
||||
""
|
||||
}
|
||||
links
|
||||
} else ""
|
||||
}
|
||||
val srcrcpList =
|
||||
iframedoc.select("div.serversList > div.server").mapNotNull {
|
||||
val datahash = it.attr("data-hash") ?: return@mapNotNull null
|
||||
val rcpLink = "$apiUrl/rcp/$datahash"
|
||||
val rcpRes = app.get(rcpLink, referer = apiUrl).text
|
||||
val srcrcpLink =
|
||||
Regex("src:\\s*'(.*)',").find(rcpRes)?.destructured?.component1()
|
||||
?: return@mapNotNull null
|
||||
"https:$srcrcpLink"
|
||||
}
|
||||
|
||||
serverslist.amap { server ->
|
||||
val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/")
|
||||
if (linkfixed.contains("/prorcp")) {
|
||||
val srcresponse = app.get(server, referer = absoluteUrl).text
|
||||
val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)")
|
||||
val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@amap
|
||||
val passRegex = Regex("""['"](.*set_pass[^"']*)""")
|
||||
val pass = passRegex.find(srcresponse)?.groupValues?.get(1)?.replace(
|
||||
Regex("""^//"""), "https://"
|
||||
)
|
||||
srcrcpList.amap { server ->
|
||||
val res = app.get(server, referer = apiUrl)
|
||||
if (res.url.contains("/prorcp")) {
|
||||
val encodedElement = res.document.select("div#reporting_content+div")
|
||||
val decodedUrl =
|
||||
decodeUrl(encodedElement.attr("id"), encodedElement.text()) ?: return@amap
|
||||
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
this.name,
|
||||
srcm3u8,
|
||||
"https://vidsrc.stream/",
|
||||
Qualities.Unknown.value,
|
||||
extractorData = pass,
|
||||
isM3u8 = true
|
||||
)
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
this.name,
|
||||
decodedUrl,
|
||||
apiUrl,
|
||||
Qualities.Unknown.value,
|
||||
isM3u8 = true
|
||||
)
|
||||
)
|
||||
} 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