diff --git a/src/zh/jinmantiantang/AndroidManifest.xml b/src/zh/jinmantiantang/AndroidManifest.xml
index 60f148625..57aa339d1 100644
--- a/src/zh/jinmantiantang/AndroidManifest.xml
+++ b/src/zh/jinmantiantang/AndroidManifest.xml
@@ -22,14 +22,6 @@
android:host="18comic.org"
android:pathPattern="/album/..*"
android:scheme="https" />
-
-
+
+
diff --git a/src/zh/jinmantiantang/build.gradle b/src/zh/jinmantiantang/build.gradle
index ed73c1c0e..f78c10db5 100644
--- a/src/zh/jinmantiantang/build.gradle
+++ b/src/zh/jinmantiantang/build.gradle
@@ -5,7 +5,7 @@ ext {
extName = 'Jinman Tiantang'
pkgNameSuffix = 'zh.jinmantiantang'
extClass = '.Jinmantiantang'
- extVersionCode = 34
+ extVersionCode = 35
isNsfw = true
}
diff --git a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt
index f0567b25f..15584e9a5 100644
--- a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt
+++ b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt
@@ -38,8 +38,7 @@ class Jinmantiantang : ParsedHttpSource(), ConfigurableSource {
private val preferences: SharedPreferences =
Injekt.get().getSharedPreferences("source_$id", 0x0000)
- override val baseUrl: String = "https://" + preferences.getString(USE_MIRROR_URL_PREF, "0")!!
- .toInt().coerceAtMost(SITE_ENTRIES_ARRAY.size - 1).let { SITE_ENTRIES_ARRAY[it] }
+ override val baseUrl: String = "https://" + preferences.baseUrl
// 处理URL请求
override val client: OkHttpClient = network.cloudflareClient
@@ -63,7 +62,7 @@ class Jinmantiantang : ParsedHttpSource(), ConfigurableSource {
}
private fun List.filterGenre(): List {
- val removedGenres = preferences.getString("BLOCK_GENRES_LIST", "")!!.substringBefore("//").trim()
+ val removedGenres = preferences.getString(BLOCK_PREF, "")!!.substringBefore("//").trim()
if (removedGenres.isEmpty()) return this
val removedList = removedGenres.lowercase().split(' ')
return this.filterNot { manga ->
diff --git a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/JinmantiantangPreferences.kt b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/JinmantiantangPreferences.kt
index 26bf28df3..9d7655688 100644
--- a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/JinmantiantangPreferences.kt
+++ b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/JinmantiantangPreferences.kt
@@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.zh.jinmantiantang
import android.content.Context
+import android.content.SharedPreferences
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
@@ -30,12 +31,19 @@ internal fun getPreferenceList(context: Context) = arrayOf(
key = USE_MIRROR_URL_PREF
title = "使用镜像网址"
entries = Array(count) { "${SITE_ENTRIES_ARRAY_DESCRIPTION[it]} (${SITE_ENTRIES_ARRAY[it]})" }
- entryValues = Array(count) { "$it" }
- summary = "使用镜像网址。需要重启软件以生效。"
+ entryValues = Array(count) { "$it" }.apply { this[count - 1] = "-1" }
+ summary = "%s\n重启后生效。"
setDefaultValue("0")
},
+ EditTextPreference(context).apply {
+ key = OVERRIDE_BASE_URL_PREF
+ title = "自定义网址"
+ summary = "需要在上一个设置选择“自定义”,重启后生效。" +
+ "不需要输入 https:// 前缀。最新网址可在 jmcomic1.bet 找到。"
+ },
+
EditTextPreference(context).apply {
key = BLOCK_PREF
title = "屏蔽词列表"
@@ -47,6 +55,18 @@ internal fun getPreferenceList(context: Context) = arrayOf(
},
)
+val SharedPreferences.baseUrl: String
+ get() {
+ val list = SITE_ENTRIES_ARRAY
+ val index = getString(USE_MIRROR_URL_PREF, "0")!!.toInt()
+ .coerceAtMost(list.size - 1)
+ return if (index == -1) {
+ getString(OVERRIDE_BASE_URL_PREF, list[0])!!
+ } else {
+ list[index]
+ }
+ }
+
internal const val BLOCK_PREF = "BLOCK_GENRES_LIST"
internal const val MAINSITE_RATELIMIT_PREF = "mainSiteRateLimitPreference"
@@ -55,26 +75,29 @@ internal const val MAINSITE_RATELIMIT_PREF_DEFAULT = 1.toString()
internal const val MAINSITE_RATELIMIT_PERIOD = "mainSiteRateLimitPeriodPreference"
internal const val MAINSITE_RATELIMIT_PERIOD_DEFAULT = 3.toString()
-internal const val USE_MIRROR_URL_PREF = "useMirrorWebsitePreference"
+private const val USE_MIRROR_URL_PREF = "useMirrorWebsitePreference"
+private const val OVERRIDE_BASE_URL_PREF = "overrideBaseUrl"
-internal val SITE_ENTRIES_ARRAY_DESCRIPTION = arrayOf(
+private val SITE_ENTRIES_ARRAY_DESCRIPTION = arrayOf(
"主站",
"海外分流",
- "中国大陆线路1",
- "中国大陆线路2/已被墙",
"东南亚线路1",
"东南亚线路2",
+ "中国大陆线路1",
+ "中国大陆线路2",
"中国大陆线路3",
+ "自定义", // -1
)
// List is based on https://jmcomic1.bet/
// Please also update AndroidManifest
-internal val SITE_ENTRIES_ARRAY = arrayOf(
+private val SITE_ENTRIES_ARRAY = arrayOf(
"18comic.vip",
"18comic.org",
- "jmcomic.onl",
- "jmcomic2.onl",
"jmcomic.me",
"jmcomic1.me",
- "jmcomic1.onl",
+ "jmcomic1.group",
+ "jmcomic2.group",
+ "jm-comic.cc",
+ "自定义", // -1
)
diff --git a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/ScrambledImageInterceptor.kt b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/ScrambledImageInterceptor.kt
index e34af92f5..4eb968265 100644
--- a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/ScrambledImageInterceptor.kt
+++ b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/ScrambledImageInterceptor.kt
@@ -10,19 +10,20 @@ import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import java.io.ByteArrayOutputStream
import java.io.InputStream
-import java.math.BigInteger
import java.security.MessageDigest
import kotlin.math.floor
object ScrambledImageInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
- val url = chain.request().url.toString()
- val response = chain.proceed(chain.request())
- if (!url.contains("media/photos", ignoreCase = true)) return response // 对非漫画图片连接直接放行
- if (url.substring(url.indexOf("photos/") + 7, url.lastIndexOf("/")).toInt() < scrambleId) return response // 对在漫画章节ID为220980之前的图片未进行图片分割,直接放行
+ val request = chain.request()
+ val url = request.url
+ val response = chain.proceed(request)
+ if (!url.toString().contains("media/photos", ignoreCase = true)) return response // 对非漫画图片连接直接放行
+ val pathSegments = url.pathSegments
+ val aid = pathSegments[pathSegments.size - 2].toInt()
+ if (aid < scrambleId) return response // 对在漫画章节ID为220980之前的图片未进行图片分割,直接放行
// 章节ID:220980(包含)之后的漫画(2020.10.27之后)图片进行了分割getRows倒序处理
- val aid = url.substring(url.indexOf("photos/") + 7, url.lastIndexOf("/")).toInt()
- val imgIndex: String = url.substringAfterLast("/").substringBefore(".")
+ val imgIndex: String = pathSegments.last().substringBefore('.')
val res = response.body.byteStream().use {
decodeImage(it, getRows(aid, imgIndex))
}
@@ -35,19 +36,19 @@ object ScrambledImageInterceptor : Interceptor {
// 图片开始分割的ID编号
private const val scrambleId = 220980
- private fun getRows(aid: Int, imgIndex: String): Int {
- fun md5(input: String): String {
- val md = MessageDigest.getInstance("MD5")
- return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
- }
+ private fun md5LastCharCode(input: String): Int {
+ val md5 = MessageDigest.getInstance("MD5")
+ val lastByte = md5.digest(input.toByteArray()).last().toInt() and 0xFF
+ return lastByte.toString(16).last().code
+ }
- return if (aid >= 421926) {
- 2 * (md5(aid.toString() + imgIndex).last().code % 8) + 2
- } else if (aid >= 268850) {
- 2 * (md5(aid.toString() + imgIndex).last().code % 10) + 2
- } else {
- 10
+ private fun getRows(aid: Int, imgIndex: String): Int {
+ val modulus = when {
+ aid >= 421926 -> 8
+ aid >= 268850 -> 10
+ else -> return 10
}
+ return 2 * (md5LastCharCode(aid.toString() + imgIndex) % modulus) + 2
}
// 对被分割的图片进行分割,排序处理