PixivComic: Use salt from chapter page (#6561)

This commit is contained in:
AlphaBoom 2024-12-10 22:28:10 +08:00 committed by Draff
parent 3a05d381e5
commit 3ecfb8529c
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
3 changed files with 15 additions and 10 deletions

View File

@ -1,7 +1,7 @@
ext {
extName = 'Pixiv Comic'
extClass = '.PixivComic'
extVersionCode = 2
extVersionCode = 3
}
apply from: "$rootDir/common.gradle"

View File

@ -8,8 +8,12 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
@ -39,10 +43,6 @@ class PixivComic : HttpSource() {
randomString()
}
private val timeAndHash by lazy {
getTimeAndHash()
}
override val client = network.cloudflareClient.newBuilder()
.addInterceptor(ShuffledImageInterceptor(key))
.addNetworkInterceptor(::tagInterceptor)
@ -244,12 +244,17 @@ class PixivComic : HttpSource() {
}
override fun pageListRequest(chapter: SChapter): Request {
val doc = client.newCall(GET(getChapterUrl(chapter), headers)).execute().asJsoup()
val salt = doc.selectFirst("script#__NEXT_DATA__")!!.data().let {
json.decodeFromString<JsonElement>(it).jsonObject["props"]!!.jsonObject["pageProps"]!!
.jsonObject["salt"]!!.jsonPrimitive.content
}
val url = apiBuilder()
.addPathSegment("episodes")
.addPathSegment(chapter.url)
.addPathSegment("read_v4")
.build()
val timeAndHash = getTimeAndHash(salt)
val header = headers.newBuilder()
.add("X-Client-Time", timeAndHash.first)
.add("X-Client-Hash", timeAndHash.second)

View File

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.extension.ja.pixivcomic
import android.annotation.SuppressLint
import android.os.Build
import okhttp3.Interceptor
import okhttp3.Response
@ -10,8 +11,6 @@ import java.util.Locale
import java.util.TimeZone
import kotlin.math.abs
private const val TIME_SALT = "M7w5HORvvX-VP4tRj2CFQOQFPocBqLvHTIbhTU36UCo"
private class NoSuchTagException(message: String) : Exception(message)
internal fun tagInterceptor(chain: Interceptor.Chain): Response {
@ -38,7 +37,7 @@ internal fun randomString(): String {
}
@OptIn(ExperimentalUnsignedTypes::class)
internal fun getTimeAndHash(): Pair<String, String> {
internal fun getTimeAndHash(salt: String): Pair<String, String> {
val timeFormatted = if (Build.VERSION.SDK_INT < 24) {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).format(Date())
.plus(getCurrentTimeZoneOffsetString())
@ -46,7 +45,7 @@ internal fun getTimeAndHash(): Pair<String, String> {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH).format(Date())
}
val saltedTimeArray = timeFormatted.plus(TIME_SALT).toByteArray()
val saltedTimeArray = timeFormatted.plus(salt).toByteArray()
val saltedTimeHash = MessageDigest.getInstance("SHA-256")
.digest(saltedTimeArray).toUByteArray()
val hexadecimalTimeHash = saltedTimeHash.joinToString("") {
@ -63,6 +62,7 @@ internal fun getTimeAndHash(): Pair<String, String> {
/**
* workaround to retrieve time zone offset for android with version lower than 24
*/
@SuppressLint("DefaultLocale")
private fun getCurrentTimeZoneOffsetString(): String {
val timeZone = TimeZone.getDefault()
val offsetInMillis = timeZone.rawOffset