From 50ebbf650a0435749af5ea6530dac94206ad477e Mon Sep 17 00:00:00 2001 From: seew3l <90949336+seew3l@users.noreply.github.com> Date: Thu, 6 Apr 2023 07:20:29 -0500 Subject: [PATCH] AiYuManga: Decrypt image list (#15963) Fix AiYuManga --- .../madara/aiyumanga/additional.gradle | 3 ++ .../madara/aiyumanga/src/AiYuManga.kt | 53 ++++++++++++++++++- .../multisrc/madara/MadaraGenerator.kt | 2 +- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 multisrc/overrides/madara/aiyumanga/additional.gradle diff --git a/multisrc/overrides/madara/aiyumanga/additional.gradle b/multisrc/overrides/madara/aiyumanga/additional.gradle new file mode 100644 index 000000000..06abd18c6 --- /dev/null +++ b/multisrc/overrides/madara/aiyumanga/additional.gradle @@ -0,0 +1,3 @@ +dependencies { + implementation(project(':lib-cryptoaes')) +} \ No newline at end of file diff --git a/multisrc/overrides/madara/aiyumanga/src/AiYuManga.kt b/multisrc/overrides/madara/aiyumanga/src/AiYuManga.kt index 72ab46c2d..5b63c1ef8 100644 --- a/multisrc/overrides/madara/aiyumanga/src/AiYuManga.kt +++ b/multisrc/overrides/madara/aiyumanga/src/AiYuManga.kt @@ -1,6 +1,13 @@ package eu.kanade.tachiyomi.extension.es.aiyumanga +import android.util.Base64 +import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES import eu.kanade.tachiyomi.multisrc.madara.Madara +import eu.kanade.tachiyomi.source.model.Page +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import org.jsoup.nodes.Document import java.text.SimpleDateFormat import java.util.Locale @@ -8,7 +15,51 @@ class AiYuManga : Madara( "AiYuManga", "https://aiyumangascanlation.com", "es", - SimpleDateFormat("d 'de' MMM 'de' yyy", Locale("es")), + SimpleDateFormat("MM/dd/yyyy", Locale("es")), ) { override val useNewChapterEndpoint = true + override val useLoadMoreSearch = true + override val chapterUrlSuffix = "" + + override val mangaDetailsSelectorStatus = "div.post-content_item:contains(Status) > div.summary-content" + + override fun pageListParse(document: Document): List { + val chapterProtector = document.getElementById("chapter-protector-data")?.html() + ?: return super.pageListParse(document) + + val password = chapterProtector + .substringAfter("wpmangaprotectornonce='") + .substringBefore("';") + val chapterData = json.parseToJsonElement( + chapterProtector + .substringAfter("chapter_data='") + .substringBefore("';") + .replace("\\/", "/"), + ).jsonObject + + val unsaltedCiphertext = Base64.decode(chapterData["ct"]!!.jsonPrimitive.content, Base64.DEFAULT) + val salt = chapterData["s"]!!.jsonPrimitive.content.decodeHex() + val ciphertext = SALTED + salt + unsaltedCiphertext + + val rawImgArray = CryptoAES.decrypt(Base64.encodeToString(ciphertext, Base64.DEFAULT), password) + val imgArrayString = json.parseToJsonElement(rawImgArray).jsonPrimitive.content + val imgArray = json.parseToJsonElement(imgArrayString).jsonArray + + return imgArray.mapIndexed { idx, it -> + Page(idx, document.location(), it.jsonPrimitive.content) + } + } + + // https://stackoverflow.com/a/66614516 + private fun String.decodeHex(): ByteArray { + check(length % 2 == 0) { "Must have an even length" } + + return chunked(2) + .map { it.toInt(16).toByte() } + .toByteArray() + } + + companion object { + val SALTED = "Salted__".toByteArray(Charsets.UTF_8) + } } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt index bb48b1bd4..f52428f5a 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt @@ -26,7 +26,7 @@ class MadaraGenerator : ThemeSourceGenerator { SingleLang("Adonis Fansub", "https://manga.adonisfansub.com", "tr", overrideVersionCode = 1), SingleLang("Adult Painful Nightz", "https://adults.painfulnightz.com", "en", isNsfw = true), SingleLang("Adult Webtoon", "https://adultwebtoon.com", "en", isNsfw = true, overrideVersionCode = 1), - SingleLang("AiYuManga", "https://aiyumangascanlation.com", "es"), + SingleLang("AiYuManga", "https://aiyumangascanlation.com", "es", overrideVersionCode = 1), SingleLang("Akuma no Tenshi", "https://akumanotenshi.com", "pt-BR", className = "AkumaNoTenshi"), SingleLang("AkuManga", "https://akumanga.com", "ar", overrideVersionCode = 1), SingleLang("Akuzenai Arts", "https://akuzenaiarts.org", "en"),