From 89e9bd43a9502df40f542be379f65916c186faba Mon Sep 17 00:00:00 2001 From: h-hyuuga <83582211+h-hyuuga@users.noreply.github.com> Date: Mon, 17 May 2021 15:50:05 -0400 Subject: [PATCH] FMReader Fixes Pt.2: The Encryption Strikes Back (#7067) * FMReader: fix fetchPageListEncrypted * Add HARSH rate limiting to ManhwaHot, ManhuaScan, HeroScan * Don't specify period= * Bump versions --- .../fmreader/heroscan/additional.gradle.kts | 4 ++++ .../fmreader/heroscan/src/HeroScan.kt | 2 ++ .../fmreader/manhuascan/additional.gradle.kts | 4 ++++ .../fmreader/manhuascan/src/ManhuaScan.kt | 7 ++++-- .../fmreader/manhwahot/additional.gradle.kts | 4 ++++ .../fmreader/manhwahot/src/ManhwaHot.kt | 8 ++++--- .../tachiyomi/multisrc/fmreader/FMReader.kt | 22 +++++++++---------- .../multisrc/fmreader/FMReaderGenerator.kt | 6 ++--- 8 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 multisrc/overrides/fmreader/heroscan/additional.gradle.kts create mode 100644 multisrc/overrides/fmreader/manhuascan/additional.gradle.kts create mode 100644 multisrc/overrides/fmreader/manhwahot/additional.gradle.kts diff --git a/multisrc/overrides/fmreader/heroscan/additional.gradle.kts b/multisrc/overrides/fmreader/heroscan/additional.gradle.kts new file mode 100644 index 000000000..10beb8157 --- /dev/null +++ b/multisrc/overrides/fmreader/heroscan/additional.gradle.kts @@ -0,0 +1,4 @@ + +dependencies { + implementation project(':lib-ratelimit') +} diff --git a/multisrc/overrides/fmreader/heroscan/src/HeroScan.kt b/multisrc/overrides/fmreader/heroscan/src/HeroScan.kt index 801467252..b8ff109b7 100644 --- a/multisrc/overrides/fmreader/heroscan/src/HeroScan.kt +++ b/multisrc/overrides/fmreader/heroscan/src/HeroScan.kt @@ -1,11 +1,13 @@ package eu.kanade.tachiyomi.extension.en.heroscan +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.multisrc.fmreader.FMReader import eu.kanade.tachiyomi.source.model.SChapter import okhttp3.OkHttpClient class HeroScan : FMReader("HeroScan", "https://heroscan.com", "en") { override val client: OkHttpClient = super.client.newBuilder() + .addInterceptor(RateLimitInterceptor(1)) .addInterceptor { chain -> val originalRequest = chain.request() chain.proceed(originalRequest).let { response -> diff --git a/multisrc/overrides/fmreader/manhuascan/additional.gradle.kts b/multisrc/overrides/fmreader/manhuascan/additional.gradle.kts new file mode 100644 index 000000000..10beb8157 --- /dev/null +++ b/multisrc/overrides/fmreader/manhuascan/additional.gradle.kts @@ -0,0 +1,4 @@ + +dependencies { + implementation project(':lib-ratelimit') +} diff --git a/multisrc/overrides/fmreader/manhuascan/src/ManhuaScan.kt b/multisrc/overrides/fmreader/manhuascan/src/ManhuaScan.kt index 79b8ac617..e254ffb84 100644 --- a/multisrc/overrides/fmreader/manhuascan/src/ManhuaScan.kt +++ b/multisrc/overrides/fmreader/manhuascan/src/ManhuaScan.kt @@ -1,12 +1,15 @@ package eu.kanade.tachiyomi.extension.en.manhuascan +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.multisrc.fmreader.FMReader import eu.kanade.tachiyomi.source.model.SChapter - import eu.kanade.tachiyomi.annotations.Nsfw - +import okhttp3.OkHttpClient @Nsfw class ManhuaScan : FMReader("ManhuaScan", "https://manhuascan.com", "en") { + override val client: OkHttpClient = super.client.newBuilder() + .addInterceptor(RateLimitInterceptor(1)) + .build() override fun fetchPageList(chapter: SChapter) = fetchPageListEncrypted(chapter) } diff --git a/multisrc/overrides/fmreader/manhwahot/additional.gradle.kts b/multisrc/overrides/fmreader/manhwahot/additional.gradle.kts new file mode 100644 index 000000000..10beb8157 --- /dev/null +++ b/multisrc/overrides/fmreader/manhwahot/additional.gradle.kts @@ -0,0 +1,4 @@ + +dependencies { + implementation project(':lib-ratelimit') +} diff --git a/multisrc/overrides/fmreader/manhwahot/src/ManhwaHot.kt b/multisrc/overrides/fmreader/manhwahot/src/ManhwaHot.kt index b9516e579..b4de74e6f 100644 --- a/multisrc/overrides/fmreader/manhwahot/src/ManhwaHot.kt +++ b/multisrc/overrides/fmreader/manhwahot/src/ManhwaHot.kt @@ -1,13 +1,15 @@ package eu.kanade.tachiyomi.extension.en.manhwahot +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.annotations.Nsfw import eu.kanade.tachiyomi.multisrc.fmreader.FMReader -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.Page -import okhttp3.Request import eu.kanade.tachiyomi.source.model.SChapter +import okhttp3.OkHttpClient @Nsfw class ManhwaHot : FMReader("ManhwaHot", "https://manhwahot.com", "en") { + override val client: OkHttpClient = super.client.newBuilder() + .addInterceptor(RateLimitInterceptor(1)) + .build() override fun fetchPageList(chapter: SChapter) = fetchPageListEncrypted(chapter) } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReader.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReader.kt index e60f291a0..1d86aa297 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReader.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReader.kt @@ -30,6 +30,7 @@ import rx.Observable import java.nio.charset.Charset import java.security.MessageDigest import java.util.Calendar +import javax.crypto.BadPaddingException import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec @@ -333,26 +334,23 @@ abstract class FMReader( * e.g ManhuaScan, HeroScan */ protected fun fetchPageListEncrypted(chapter: SChapter): Observable> { - fun stringAssignment(varname: String, script: String) = Regex("""var\s+$varname\s*=\s*"([^"]*)"""").find(script)?.groups?.get(1)?.value + fun stringAssignment(varname: String, script: String) = Regex("""(?:let|var)\s+$varname\s*=\s*"([^"]*)"""").find(script)?.groups?.get(1)?.value fun pageList(s: String) = Regex("https.+?(?=https|\"$)").findAll(s).map { it.groups[0]!!.value.replace("\\/", "/") } fun pageListRequest(id: String, server: Int = 1) = POST("$baseUrl/app/manga/controllers/cont.chapterServer$server.php", headers, "id=$id".toRequestBody("application/x-www-form-urlencoded; charset=UTF-8".toMediaTypeOrNull())) return client.newCall(GET("$baseUrl${chapter.url}", headers)).asObservableSuccess().concatMap { htmlResponse -> val soup = htmlResponse.asJsoup() soup.selectFirst("head > script[type='text/javascript']")?.data()?.let { params -> - val chapterId = stringAssignment("chapter_id", params) - val csrfToken = stringAssignment("csrf_token", params) - if (chapterId == null || csrfToken == null) - null - else + stringAssignment("chapter_id", params)?.let { chapterId -> client.newCall(pageListRequest(chapterId)).asObservableSuccess() .map { jsonResponse -> - pageList( - crypto.aes_decrypt( - jsonResponse.body!!.string(), - crypto.md5("$csrfToken$csrfToken").toByteArray() - ) - ).mapIndexed { i, imgUrl -> Page(i, "", imgUrl) }.toList() + try { + pageList(crypto.aes_decrypt(jsonResponse.body!!.string(), "4xje8fvkub2d3mb5cy9rv661zyjakbcn".toByteArray())) + .mapIndexed { i, imgUrl -> Page(i, "", imgUrl) }.toList() + } catch (_: BadPaddingException) { + throw RuntimeException("Decryption Failed") + } } + } } ?: Observable.just(emptyList()) } } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReaderGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReaderGenerator.kt index 237065b06..08d8fa476 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReaderGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/fmreader/FMReaderGenerator.kt @@ -17,17 +17,17 @@ class FMReaderGenerator : ThemeSourceGenerator { override val sources = listOf( SingleLang("Epik Manga", "https://www.epikmanga.com", "tr"), - SingleLang("HeroScan", "https://heroscan.com", "en", overrideVersionCode = 1), + SingleLang("HeroScan", "https://heroscan.com", "en", overrideVersionCode = 2), SingleLang("KissLove", "https://kissaway.net", "ja"), SingleLang("LHTranslation", "https://lhtranslation.net", "en", overrideVersionCode = 1), SingleLang("Manga-TR", "https://manga-tr.com", "tr", className = "MangaTR"), - SingleLang("ManhuaScan", "https://manhuascan.com", "en", isNsfw = true, overrideVersionCode = 2), + SingleLang("ManhuaScan", "https://manhuascan.com", "en", isNsfw = true, overrideVersionCode = 3), SingleLang("Manhwa18", "https://manhwa18.com", "en", isNsfw = true), MultiLang("Manhwa18.net", "https://manhwa18.net", listOf("en", "ko"), className = "Manhwa18NetFactory", isNsfw = true), SingleLang("RawLH", "https://lovehug.net", "ja"), SingleLang("Say Truyen", "https://saytruyen.com", "vi"), SingleLang("KSGroupScans", "https://ksgroupscans.com", "en"), - SingleLang("ManhwaHot", "https://manhwahot.com", "en", isNsfw = true), + SingleLang("ManhwaHot", "https://manhwahot.com", "en", isNsfw = true, overrideVersionCode=1), // Sites that went down //SingleLang("18LHPlus", "https://18lhplus.com", "en", className = "EighteenLHPlus"), //SingleLang("HanaScan (RawQQ)", "https://hanascan.com", "ja", className = "HanaScanRawQQ"),