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 } // 对被分割的图片进行分割,排序处理