fix page list (#15098)

* fix page list

* guard with whitespace

* replace http with https to skip 301s
This commit is contained in:
jailbreak-bypass-forms 2023-01-25 17:32:11 +07:00 committed by GitHub
parent dfcd66b3fc
commit 84a1235b5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 25 deletions

View File

@ -93,25 +93,27 @@ class ConstellarScans : MangaThemesia("Constellar Scans", "https://constellarsca
.build()
override fun pageListParse(document: Document): List<Page> {
val tsData = TS_DATA_RE.find(document.select("script").html())?.groupValues?.get(1)
?: return super.pageListParse(document)
val descrambledData = descrambleString(tsData).trim()
// check if the object can be parsed with JSON, else assume it is encrypted
//
// done because constellarscans have shit code and would sometimes give us an invalid key
// for no reason
return try {
val parsedTsData = json.parseToJsonElement(descrambledData).jsonObject
val imageList = parsedTsData["sources"]!!.jsonArray[0].jsonObject["images"]!!.jsonArray
imageList.mapIndexed { idx, it ->
Page(idx, imageUrl = it.jsonPrimitive.content)
}
} catch (_: IllegalArgumentException) {
val obfuscatedCode = document.select("script:containsData(_0x)").html()
val tsDataEncrypted = TS_DATA_RE.find(obfuscatedCode)?.groupValues?.get(1)
if (tsDataEncrypted != null) {
val descrambledData = descrambleString(tsDataEncrypted).trim()
val match = DESCRAMBLING_KEY_RE.find(descrambledData)?.value
?: throw Exception("Did not receive valid decryption key. Try opening the chapter again.")
Log.d("constellarscans", "device-limited chapter: $match")
decodeDeviceLimitedChapter(match)
return decodeDeviceLimitedChapter(match)
}
val scripts = document.select("script").html()
val tsData = JS_FUNC_RE.findAll(obfuscatedCode).firstNotNullOf {
val func = it.groupValues[1]
val tsDataFuncRe = Regex("""$func\s*\(\s*['"]([\da-z]+?)['"]\s*\)""", RegexOption.IGNORE_CASE)
val match = tsDataFuncRe.find(scripts)?.groupValues?.get(1)
?: return@firstNotNullOf null
descrambleString(match).trim()
}
val tsDataObject = json.parseToJsonElement(tsData).jsonObject
return tsDataObject["sources"]!!.jsonArray[0].jsonObject["images"]!!.jsonArray.mapIndexed { index, jsonElement ->
Page(index, imageUrl = jsonElement.jsonPrimitive.content.replace("http://", "https://"))
}
}
@ -122,10 +124,16 @@ class ConstellarScans : MangaThemesia("Constellar Scans", "https://constellarsca
.header("Sec-Fetch-Site", "same-origin")
.build()
private fun sumOfDigits(input: String): Int = input.sumOf { it.toString().toInt() }
private fun descrambleString(input: String): String =
input.replace(NOT_DIGIT_RE, "")
.chunked(2)
.joinToString("") { (it.toInt() + 32).toChar().toString() }
.chunked(6)
.map {
val charCode = sumOfDigits(it.substring(0..2)) * 10 + sumOfDigits(it.substring(3)) + 32
charCode.toChar()
}
.joinToString("")
private fun decodeDeviceLimitedChapter(fullKey: String): List<Page> {
if (!DESCRAMBLING_KEY_RE.matches(fullKey)) {
@ -215,13 +223,9 @@ class ConstellarScans : MangaThemesia("Constellar Scans", "https://constellarsca
const val LOOKUP_STRING_ALNUM =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
val NOT_DIGIT_RE = Regex("""\D""")
val JS_FUNC_RE = Regex("""function (.+?)\s*\(""")
// We know that `ts_reader.run` accepts a JSON object, which contains `{"`, or in Constellar's
// encoding scheme, 91 02.
val TS_DATA_RE = Regex(
"""['"]([\da-z]*?9[a-z]*?1[a-z]*?0[a-z]*?2[\da-z]+?)['"]""",
RegexOption.IGNORE_CASE
)
val TS_DATA_RE = Regex("""\(\s*['"]([\da-z]+?)['"]\s*\)""", RegexOption.IGNORE_CASE)
// The decoding algorithm looks for a hex number in 32..33, so we write our regex accordingly
val DESCRAMBLING_KEY_RE =

View File

@ -25,7 +25,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Azure Scans", "https://azuremanga.com", "en", overrideVersionCode = 1),
SingleLang("Boosei", "https://boosei.net", "id", overrideVersionCode = 2),
SingleLang("Clayrer", "https://clayrer.net", "es"),
SingleLang("Constellar Scans", "https://constellarscans.com", "en", isNsfw = true, overrideVersionCode = 6),
SingleLang("Constellar Scans", "https://constellarscans.com", "en", isNsfw = true, overrideVersionCode = 7),
SingleLang("Cosmic Scans", "https://cosmicscans.com", "en", overrideVersionCode = 1),
SingleLang("Diskus Scan", "https://diskusscan.com", "pt-BR", overrideVersionCode = 7),
SingleLang("Dojing.net", "https://dojing.net", "id", isNsfw = true, className = "DojingNet"),