Skip to content

Commit

Permalink
fix(en/kickassanine): Fix extractor & update urls (#3012)
Browse files Browse the repository at this point in the history
  • Loading branch information
Secozzi authored Mar 6, 2024
1 parent b16b8b8 commit 39fba62
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/en/kickassanime/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'KickAssAnime'
extClass = '.KickAssAnime'
extVersionCode = 37
extVersionCode = 38
}

apply from: "$rootDir/common.gradle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.Locale

class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() {
Expand All @@ -53,11 +54,10 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() {

private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
.clearBaseUrl()
}

private val json = Json {
ignoreUnknownKeys = true
}
private val json: Json by injectLazy()

// ============================== Popular ===============================
override fun popularAnimeRequest(page: Int) = GET("$apiUrl/popular?page=$page")
Expand Down Expand Up @@ -290,6 +290,17 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() {
).reversed()
}

private fun SharedPreferences.clearBaseUrl(): SharedPreferences {
if (getString(PREF_DOMAIN_KEY, "")!! in PREF_DOMAIN_ENTRY_VALUES) {
return this
}
edit()
.remove(PREF_DOMAIN_KEY)
.putString(PREF_DOMAIN_KEY, PREF_DOMAIN_DEFAULT)
.apply()
return this
}

companion object {
private val SERVERS = arrayOf("DuckStream", "BirdStream", "VidStreaming")

Expand Down Expand Up @@ -323,9 +334,9 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() {

private const val PREF_DOMAIN_KEY = "preferred_domain"
private const val PREF_DOMAIN_TITLE = "Preferred domain (requires app restart)"
private const val PREF_DOMAIN_DEFAULT = "https://kickassanime.am"
private val PREF_DOMAIN_ENTRIES = arrayOf("kickassanime.am", "kaas.to", "kaas.ro")
private val PREF_DOMAIN_ENTRY_VALUES = arrayOf("https://kickassanime.am", "https://kaas.to", "https://kaas.ro")
private const val PREF_DOMAIN_DEFAULT = "https://kaas.to"
private val PREF_DOMAIN_ENTRIES = arrayOf("kaas.to", "kaas.ro", "kickassanimes.io", "www1.kickassanime.mx")
private val PREF_DOMAIN_ENTRY_VALUES = PREF_DOMAIN_ENTRIES.map { "https://$it" }.toTypedArray()

private const val PREF_HOSTER_KEY = "hoster_selection"
private const val PREF_HOSTER_TITLE = "Enable/Disable Hosts"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES.decodeHex
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.parseAs
import kotlinx.serialization.json.Json
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
Expand All @@ -20,27 +18,6 @@ class KickAssAnimeExtractor(
private val json: Json,
private val headers: Headers,
) {
// Stolen from AniWatch
// Prevent (automatic) caching the .JS file for different episodes, because it
// changes everytime, and a cached old .js will have a invalid AES password,
// invalidating the decryption algorithm.
// We cache it manually when initializing the class.
private val cacheControl = CacheControl.Builder().noStore().build()
private val newClient = client.newBuilder()
.cache(null)
.build()

private val keyMaps by lazy {
buildMap {
put("bird", newClient.newCall(GET("https://raw.githubusercontent.com/enimax-anime/kaas/bird/key.txt", cache = cacheControl)).execute().body.string().toByteArray())
put("duck", newClient.newCall(GET("https://raw.githubusercontent.com/enimax-anime/kaas/duck/key.txt", cache = cacheControl)).execute().body.string().toByteArray())
}
}

private val signaturesMap by lazy {
newClient.newCall(GET("https://raw.githubusercontent.com/enimax-anime/gogo/main/KAA.json", cache = cacheControl)).execute().parseAs<Map<String, List<String>>>()
}

fun videosFromUrl(url: String, name: String): List<Video> {
val host = url.toHttpUrl().host
val mid = if (name == "DuckStream") "mid" else "id"
Expand All @@ -51,11 +28,11 @@ class KickAssAnimeExtractor(
val html = client.newCall(GET(url, headers)).execute().body.string()

val key = when (name) {
"VidStreaming" -> keyMaps["duck"]!!
"DuckStream" -> keyMaps["duck"]!!
"BirdStream" -> keyMaps["bird"]!!
"VidStreaming" -> "e13d38099bf562e8b9851a652d2043d3"
"DuckStream" -> "4504447b74641ad972980a6b8ffd7631"
"BirdStream" -> "4b14d0ff625163e3c9c7a47926484bf2"
else -> return emptyList()
}
}.toByteArray()

val (sig, timeStamp, route) = getSignature(html, name, query, key) ?: return emptyList()
val sourceUrl = buildString {
Expand Down Expand Up @@ -127,9 +104,9 @@ class KickAssAnimeExtractor(

private fun getSignature(html: String, server: String, query: String, key: ByteArray): Triple<String, String, String>? {
val order = when (server) {
"VidStreaming" -> signaturesMap["vid"]!!
"DuckStream" -> signaturesMap["duck"]!!
"BirdStream" -> signaturesMap["bird"]!!
"VidStreaming" -> listOf("IP", "USERAGENT", "ROUTE", "MID", "TIMESTAMP", "KEY")
"DuckStream" -> listOf("IP", "USERAGENT", "ROUTE", "MID", "TIMESTAMP", "KEY")
"BirdStream" -> listOf("IP", "USERAGENT", "ROUTE", "MID", "KEY")
else -> return null
}

Expand Down

0 comments on commit 39fba62

Please sign in to comment.