Picacomic: Fix Channel logic error (#8555)

* Adding a Referer value to the request header increases the possibility of circumventing Cloudflare.

* Adding a Referer value to the request header increases the possibility of circumventing Cloudflare.

* Adding a Referer value to the request header increases the possibility of circumventing Cloudflare.

* Update src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt

* Fix: Channel logic error

* Fix: Channel logic error

* Fix: Channel logic error

* Fix: Channel logic error

---------

Co-authored-by: Vetle Ledaal <vetle.ledaal@gmail.com>
This commit is contained in:
peakedshout 2025-04-25 01:11:07 +08:00 committed by Draff
parent 2edb3b6164
commit e853527587
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
4 changed files with 101 additions and 3 deletions

View File

@ -1,7 +1,7 @@
ext {
extName = 'Picacomic'
extClass = '.Picacomic'
extVersionCode = 6
extVersionCode = 7
isNsfw = true
}

View File

@ -0,0 +1,75 @@
package eu.kanade.tachiyomi.extension.zh.picacomic
import android.content.SharedPreferences
import eu.kanade.tachiyomi.network.GET
import keiyoushi.utils.parseAs
import okhttp3.Dns
import okhttp3.Headers
import okhttp3.OkHttpClient
import okio.IOException
import java.net.InetAddress
class ChannelDns(
private val baseHost: String,
private val client: OkHttpClient,
private val preferences: SharedPreferences,
) : Dns {
private val defaultInitUrl = "http://68.183.234.72/init"
private var channel = listOf<String>()
override fun lookup(hostname: String): List<InetAddress> {
if (!hostname.endsWith(baseHost)) {
return Dns.SYSTEM.lookup(hostname)
}
val ch = preferences.getString(APP_CHANNEL, "2")!!
return when (ch) {
"2" -> listOf(InetAddress.getByName(getChannelHost(0)))
"3" -> listOf(InetAddress.getByName(getChannelHost(1)))
else -> Dns.SYSTEM.lookup(hostname)
}
}
private fun getChannelHost(index: Int): String {
if (channel.size > index) {
return channel[index]
}
val chUrl =
preferences.getString(APP_CHANNEL_URL, defaultInitUrl)?.takeIf { it.isNotBlank() }
?: defaultInitUrl
val request = GET(
url = chUrl,
headers = Headers.headersOf(
"Accept-Encoding",
"gzip",
"User-Agent",
"okhttp/3.8.1",
),
)
try {
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
throw Exception("Unexpected ${request.url} code ${response.code}")
}
val responseBody = response.body.string()
val ch = responseBody.parseAs<PicaChannel>()
if (ch.status != "ok") {
throw Exception("Unexpected ${request.url} status ${ch.status}")
}
channel = ch.addresses
if (channel.size <= index) {
throw Exception("Unexpected ${request.url} unable to obtain the target channel address")
}
return channel[index]
} catch (e: Exception) {
throw IOException(e.message)
}
}
}

View File

@ -99,3 +99,9 @@ data class PicaImage(
val path: String,
val fileServer: String,
)
@Serializable
data class PicaChannel(
val status: String,
val addresses: List<String>,
)

View File

@ -23,6 +23,7 @@ import kotlinx.serialization.json.decodeFromJsonElement
import okhttp3.Headers
import okhttp3.Headers.Companion.toHeaders
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
@ -41,12 +42,15 @@ class Picacomic : HttpSource(), ConfigurableSource {
private val preferences: SharedPreferences = getPreferences()
override val client: OkHttpClient = network.client.newBuilder()
.dns(ChannelDns(baseUrl.removePrefix("https://picaapi."), network.client, preferences)).build()
private val blocklist = preferences.getString("BLOCK_GENRES", "")!!
.split(',').map { it.trim() }
private val basicHeaders = mapOf(
"api-key" to "C69BAF41DA5ABD1FFEDC6D2FEA56B",
"app-channel" to preferences.getString("APP_CHANNEL", "2")!!,
"app-channel" to preferences.getString(APP_CHANNEL, "2")!!,
"app-version" to "2.2.1.3.3.4",
"app-uuid" to "defaultUuid",
"app-platform" to "android",
@ -441,7 +445,7 @@ class Picacomic : HttpSource(), ConfigurableSource {
}.let(screen::addPreference)
ListPreference(screen.context).apply {
key = "APP_CHANNEL"
key = APP_CHANNEL
title = "分流"
entries = arrayOf("1", "2", "3")
entryValues = entries
@ -451,5 +455,18 @@ class Picacomic : HttpSource(), ConfigurableSource {
preferences.edit().putString(key, newValue as String).commit()
}
}.let(screen::addPreference)
EditTextPreference(screen.context).apply {
key = APP_CHANNEL_URL
title = "分流url"
summary =
"自定义用于获取分流2、3的目标地址分流1不受影响如果之前获取成功了需要重启才能生效如果出现超时可以多重试几次"
setOnPreferenceChangeListener { _, newValue ->
preferences.edit().putString(APP_CHANNEL_URL, newValue as String).commit()
}
}.let(screen::addPreference)
}
}
const val APP_CHANNEL = "APP_CHANNEL"
const val APP_CHANNEL_URL = "APP_CHANNEL_URL"