Fix #550 and Improve KwikExtractor Decrypt Function #551
4 changed files with 23 additions and 69 deletions
|
@ -1,7 +1,7 @@
|
|||
ext {
|
||||
extName = 'AnimePahe'
|
||||
extClass = '.AnimePahe'
|
||||
extVersionCode = 27
|
||||
extVersionCode = 28
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
||||
|
|
|
@ -19,9 +19,6 @@ import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
|||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import eu.kanade.tachiyomi.util.parseAs
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Request
|
||||
|
@ -67,16 +64,8 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||
* @see episodeListRequest
|
||||
*/
|
||||
override fun animeDetailsRequest(anime: SAnime): Request {
|
||||
val animeId = anime.getId()
|
||||
// We're using coroutines here to run it inside another thread and
|
||||
// prevent android.os.NetworkOnMainThreadException when trying to open
|
||||
// webview or share it.
|
||||
val session = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
fetchSession(anime.title, animeId)
|
||||
}
|
||||
}
|
||||
return GET("$baseUrl/anime/$session?anime_id=$animeId")
|
||||
val session = anime.getSession()
|
||||
return GET("$baseUrl/anime/$session")
|
||||
}
|
||||
|
||||
override fun animeDetailsParse(response: Response): SAnime {
|
||||
|
@ -106,8 +95,8 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||
SAnime.create().apply {
|
||||
title = anime.title
|
||||
thumbnail_url = anime.snapshot
|
||||
val animeId = anime.id
|
||||
setUrlWithoutDomain("/anime/?anime_id=$animeId")
|
||||
val sessionId = anime.anime_session
|
||||
setUrlWithoutDomain("/anime/?session_id=$sessionId")
|
||||
artist = anime.fansub
|
||||
}
|
||||
}
|
||||
|
@ -124,8 +113,8 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||
SAnime.create().apply {
|
||||
title = anime.title
|
||||
thumbnail_url = anime.poster
|
||||
val animeId = anime.id
|
||||
setUrlWithoutDomain("/anime/?anime_id=$animeId")
|
||||
val sessionId = anime.session
|
||||
setUrlWithoutDomain("/anime/?session_id=$sessionId")
|
||||
}
|
||||
}
|
||||
return AnimesPage(animeList, false)
|
||||
|
@ -146,7 +135,7 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||
* @see animeDetailsRequest
|
||||
*/
|
||||
override fun episodeListRequest(anime: SAnime): Request {
|
||||
val session = fetchSession(anime.title, anime.getId())
|
||||
val session = anime.getSession()
|
||||
return GET("$baseUrl/api?m=release&id=$session&sort=episode_desc&page=1")
|
||||
}
|
||||
|
||||
|
@ -310,15 +299,6 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||
}
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
private fun fetchSession(title: String, animeId: String): String {
|
||||
return client.newCall(GET("$baseUrl/api?m=search&q=$title"))
|
||||
.execute()
|
||||
.body.string()
|
||||
.substringAfter("\"id\":$animeId")
|
||||
.substringAfter("\"session\":\"")
|
||||
.substringBefore("\"")
|
||||
}
|
||||
|
||||
private fun parseStatus(statusString: String): Int {
|
||||
return when (statusString) {
|
||||
"Currently Airing" -> SAnime.ONGOING
|
||||
|
@ -327,7 +307,7 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun SAnime.getId() = url.substringAfterLast("?anime_id=").substringBefore("\"")
|
||||
private fun SAnime.getSession() = url.substringAfterLast("?session_id=").substringBefore("\"")
|
||||
|
||||
private fun String.toDate(): Long {
|
||||
return runCatching {
|
||||
|
|
|
@ -35,7 +35,6 @@ import okhttp3.FormBody
|
|||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import kotlin.math.pow
|
||||
|
||||
class KwikExtractor(private val client: OkHttpClient) {
|
||||
private var cookies: String = ""
|
||||
|
@ -108,52 +107,25 @@ class KwikExtractor(private val client: OkHttpClient) {
|
|||
}
|
||||
|
||||
private fun decrypt(fullString: String, key: String, v1: Int, v2: Int): String {
|
||||
var r = ""
|
||||
val keyIndexMap = key.withIndex().associate { it.value to it.index }
|
||||
val sb = StringBuilder()
|
||||
var i = 0
|
||||
val toFind = key[v2]
|
||||
|
||||
while (i < fullString.length) {
|
||||
var s = ""
|
||||
|
||||
while (fullString[i] != key[v2]) {
|
||||
s += fullString[i]
|
||||
++i
|
||||
val nextIndex = fullString.indexOf(toFind, i)
|
||||
val decodedCharStr = buildString {
|
||||
for (j in i until nextIndex) {
|
||||
append(keyIndexMap[fullString[j]] ?: -1)
|
||||
}
|
||||
}
|
||||
var j = 0
|
||||
|
||||
while (j < key.length) {
|
||||
s = s.replace(key[j].toString(), j.toString())
|
||||
++j
|
||||
}
|
||||
r += (getString(s, v2).toInt() - v1).toChar()
|
||||
++i
|
||||
}
|
||||
return r
|
||||
}
|
||||
i = nextIndex + 1
|
||||
|
||||
private fun getString(content: String, s1: Int): String {
|
||||
val s2 = 10
|
||||
val characterMap = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"
|
||||
|
||||
val slice2 = characterMap.slice(0 until s2)
|
||||
var acc: Long = 0
|
||||
|
||||
for ((n, i) in content.reversed().withIndex()) {
|
||||
acc += when (isNumber("$i")) {
|
||||
true -> "$i".toLong()
|
||||
false -> 0L
|
||||
} * s1.toDouble().pow(n.toDouble()).toInt()
|
||||
val decodedChar = (decodedCharStr.toInt(v2) - v1).toChar()
|
||||
sb.append(decodedChar)
|
||||
}
|
||||
|
||||
var k = ""
|
||||
|
||||
while (acc > 0) {
|
||||
k = slice2[(acc % s2).toInt()] + k
|
||||
acc = (acc - (acc % s2)) / s2
|
||||
}
|
||||
|
||||
return when (k != "") {
|
||||
true -> k
|
||||
false -> "0"
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ data class LatestAnimeDto(
|
|||
@SerialName("anime_id")
|
||||
val id: Int,
|
||||
val fansub: String,
|
||||
val anime_session: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
@ -30,6 +31,7 @@ data class SearchResultDto(
|
|||
val title: String,
|
||||
val poster: String,
|
||||
val id: Int,
|
||||
val session: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue