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