Overhaul 2025 (See PR for changes)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package eu.kanade.tachiyomi.multisrc.gmanga
|
||||
|
||||
import android.util.Base64
|
||||
import java.security.MessageDigest
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.spec.IvParameterSpec
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
fun decrypt(responseData: String): String {
|
||||
val enc = responseData.split("|")
|
||||
val secretKey = enc[3].sha256().hexStringToByteArray()
|
||||
|
||||
return enc[0].aesDecrypt(secretKey, enc[2])
|
||||
}
|
||||
|
||||
private fun String.hexStringToByteArray(): ByteArray {
|
||||
val len = length
|
||||
val data = ByteArray(len / 2)
|
||||
var i = 0
|
||||
while (i < len) {
|
||||
data[i / 2] = (
|
||||
(Character.digit(this[i], 16) shl 4) +
|
||||
Character.digit(this[i + 1], 16)
|
||||
).toByte()
|
||||
i += 2
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
private fun String.sha256(): String {
|
||||
return MessageDigest
|
||||
.getInstance("SHA-256")
|
||||
.digest(toByteArray())
|
||||
.fold("") { str, it -> str + "%02x".format(it) }
|
||||
}
|
||||
|
||||
private fun String.aesDecrypt(secretKey: ByteArray, ivString: String): String {
|
||||
val c = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
||||
val sk = SecretKeySpec(secretKey, "AES")
|
||||
val iv = IvParameterSpec(Base64.decode(ivString.toByteArray(Charsets.UTF_8), Base64.DEFAULT))
|
||||
c.init(Cipher.DECRYPT_MODE, sk, iv)
|
||||
|
||||
val byteStr = Base64.decode(toByteArray(Charsets.UTF_8), Base64.DEFAULT)
|
||||
return String(c.doFinal(byteStr))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package eu.kanade.tachiyomi.multisrc.mangaworld
|
||||
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import okhttp3.Cookie
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
|
||||
class CookieRedirectInterceptor(private val client: OkHttpClient) : Interceptor {
|
||||
private val cookieRegex = Regex("""document\.cookie="(MWCookie[^"]+)""")
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
val response = chain.proceed(request)
|
||||
|
||||
val contentType = response.header("content-type")
|
||||
if (contentType != null && contentType.startsWith("image/", ignoreCase = true)) {
|
||||
return response
|
||||
}
|
||||
|
||||
// ignore requests that already have completed the JS challenge
|
||||
if (response.headers["vary"] != null) return response
|
||||
|
||||
val content = response.body.string()
|
||||
val results = cookieRegex.find(content)
|
||||
?: return response.newBuilder().body(content.toResponseBody(response.body.contentType())).build()
|
||||
val (cookieString) = results.destructured
|
||||
return chain.proceed(loadCookie(request, cookieString))
|
||||
}
|
||||
|
||||
private fun loadCookie(request: Request, cookieString: String): Request {
|
||||
val cookie = Cookie.parse(request.url, cookieString)!!
|
||||
client.cookieJar.saveFromResponse(request.url, listOf(cookie))
|
||||
val headers = request.headers.newBuilder()
|
||||
.add("Cookie", cookie.toString())
|
||||
.build()
|
||||
return GET(request.url, headers)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user