Updated VidSrc encryption methods (#1205)

This commit is contained in:
RowdyRushya 2024-07-20 15:06:04 -07:00 committed by GitHub
parent 4c7379c766
commit 0c418fdf9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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
}
}