From e38cb68ed99bd08c1823d5d50806375085171325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Franti=C5=A1ek=20Straka?= Date: Tue, 8 Apr 2025 11:30:49 +0200 Subject: [PATCH 01/13] header fetching --- .../animeextension/en/aniplay/AniPlay.kt | 63 ++++++++++++++----- .../animeextension/en/aniplay/AniPlayDto.kt | 8 +++ 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt index e23034ec..b9cf0293 100644 --- a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt +++ b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt @@ -30,6 +30,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.io.IOException import java.text.SimpleDateFormat +import java.util.Date import java.util.Locale @Suppress("unused") @@ -358,6 +359,50 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { return if (bracketCount == 0) input.substring(startIndex - 1, endIndex) else null } + private var lastHeaderFetch = 0L + private fun fetchHeaders() { + val currentTimestamp = Date().time + val timeout = lastHeaderFetch + (HEADERS_TIMEOUT_MINUTES * 60 * 1000) + // check only after 15 minutes + if (timeout > currentTimestamp) { + Log.i("AniPlay", "Skipping header update. $timeout > $currentTimestamp (${timeout - currentTimestamp}).") + return + } + + val baseUrl = Base64.decode("aHR0cHM6Ly9qb3NlZmZzdHJha2EuZ2l0aHViLmlvL2FuaXBsYXktaGVhZGVycy8=", Base64.DEFAULT).toString(Charsets.UTF_8) + + val preferredDomain = preferences.getString(PREF_DOMAIN_KEY, PREF_DOMAIN_DEFAULT)!! + + try { + val url = ("$baseUrl$preferredDomain/headers.json").toHttpUrl() + val response = client.newCall(Request(url)).execute() + val body = response.body.string() + val domainHeaders = body.parseAs() + domainsHeaders[preferredDomain] = domainHeaders + Log.i("AniPlay", "Fetched headers($preferredDomain): $domainHeaders") + } catch (e: Exception) { + Log.e("AniPlay", "Failed to fetch new headers: \"e\"") + return + } + + lastHeaderFetch = Date().time + } + + private fun getHeaderValue(serverHost: String, key: String): String { + fetchHeaders() + try { + val domainHeaders = domainsHeaders[serverHost] ?: throw Exception("Bad host: $serverHost") + return when (key) { + NEXT_ACTION_EPISODE_LIST -> domainHeaders.episodes + NEXT_ACTION_SOURCES_LIST -> domainHeaders.sources + else -> throw Exception("Bad key: $key") + } + } catch (e: Exception) { + Log.e("AniPlay", "getHeaderValue error. $e. (s:${domainsHeaders.size}, l:$lastHeaderFetch)") + throw e + } + } + /* ====================================== Preferences ====================================== */ override fun setupPreferenceScreen(screen: PreferenceScreen) { @@ -485,10 +530,6 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { } ?: 0L } - private fun getHeaderValue(serverHost: String, key: String): String { - return HEADER_NEXT_ACTION[serverHost]?.get(key) ?: throw Exception("Bad host/key") - } - companion object { private const val PREF_DOMAIN_KEY = "domain" private val PREF_DOMAIN_ENTRIES = arrayOf("aniplaynow.live (default)", "aniplay.lol (backup/experimental)") @@ -524,18 +565,12 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { private const val NEXT_ACTION_EPISODE_LIST = "NEXT_ACTION_EPISODE_LIST" private const val NEXT_ACTION_SOURCES_LIST = "NEXT_ACTION_SOURCES_LIST" - private val HEADER_NEXT_ACTION = mapOf( - PREF_DOMAIN_ENTRY_VALUES[0] to mapOf( - "NEXT_ACTION_EPISODE_LIST" to "7f07777b5f74e3edb312e0b718a560f9d3ad21aeba", - "NEXT_ACTION_SOURCES_LIST" to "7f11490e43dca1ed90fcb5b90bac1e5714a3e11232", - ), - PREF_DOMAIN_ENTRY_VALUES[1] to mapOf( - "NEXT_ACTION_EPISODE_LIST" to "7f57233b7a6486e8211b883c502fa0450775f0ee98", - "NEXT_ACTION_SOURCES_LIST" to "7f48c7ffeb25edece852102a65d794a1dffa37aaac", - ), - ) private const val PROXY_URL = "https://prox.aniplaynow.live" + private const val HEADERS_TIMEOUT_MINUTES = 15 + private val DATE_FORMATTER = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH) + + private var domainsHeaders = mutableMapOf() } } diff --git a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlayDto.kt b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlayDto.kt index 4f909466..b6ba3e80 100644 --- a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlayDto.kt +++ b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlayDto.kt @@ -79,3 +79,11 @@ data class EpisodeExtra( val episodeId: String, val hasDub: Boolean, ) + +// Headers +@Serializable +data class DomainHeaders( + val episodes: String, + val sources: String, + val time: Long, +) -- 2.47.2 From 6aa8fd74551f9ae6bb9bc850d701bf079ffda12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Franti=C5=A1ek=20Straka?= Date: Tue, 8 Apr 2025 11:30:57 +0200 Subject: [PATCH 02/13] version bump --- src/en/aniplay/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/aniplay/build.gradle b/src/en/aniplay/build.gradle index edce2f4c..e7d1129f 100644 --- a/src/en/aniplay/build.gradle +++ b/src/en/aniplay/build.gradle @@ -2,7 +2,7 @@ ext { extName = 'AniPlay' extClass = '.AniPlay' themePkg = 'anilist' - overrideVersionCode = 15 + overrideVersionCode = 16 } apply from: "$rootDir/common.gradle" -- 2.47.2 From 01f5c6aa3d6558c158a0c45ab594d090fbf3dd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Franti=C5=A1ek=20Straka?= Date: Tue, 8 Apr 2025 14:39:18 +0200 Subject: [PATCH 03/13] modified video fetching --- .../animeextension/en/aniplay/AniPlay.kt | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt index b9cf0293..6de0a7f5 100644 --- a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt +++ b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt @@ -291,19 +291,41 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { } try { - val url = getProxiedUrl(defaultSource.url, serverName, episodeData.response.headers?.Referer) - return playlistUtils.extractFromHls( - playlistUrl = url, - videoNameGen = { quality -> "$serverName - $quality - $typeName" }, - subtitleList = subtitles, - masterHeadersGen = { baseHeaders: Headers, _: String -> - baseHeaders.newBuilder().apply { + return when (serverName) { + // yuki + PREF_SERVER_ENTRIES[1] -> { + // proxy wont work due to aniplay using /m3u8-proxy for playlists and /ts-proxy for segments, not sure how to tell that to aniyomi + // val url = "https://yukiprox.aniplaynow.live/m3u8-proxy?url=${defaultSource.url}&headers={\"Referer\":\"https://megacloud.club/\"}" + + //and using raw server is kinda cheap +// playlistUtils.extractFromHls( +// playlistUrl = defaultSource.url, +// videoNameGen = { quality -> "$serverName - $quality - $typeName" }, +// subtitleList = subtitles, +// masterHeadersGen = { baseHeaders: Headers, _: String -> +// baseHeaders.newBuilder().apply { +// set("Accept", "*/*") +// set("Origin", "https://megacloud.club") +// set("Referer", "https://megacloud.club/") +// }.build() +// }, +// ) + emptyList() + } + // pahe + PREF_SERVER_ENTRIES[2] -> { + val url = "https://prox.aniplaynow.live/?url=${defaultSource.url}&ref=https://kwik.si" + val headers = headers.newBuilder().apply { set("Accept", "*/*") set("Origin", baseUrl) set("Referer", "$baseUrl/") }.build() - }, - ) + listOf(Video(url, "$serverName - Video - $typeName", url, headers, subtitles, listOf())) + } + else -> { + emptyList() + } + } } catch (e: Exception) { Log.e("AniPlay", "processEpisodeData extractFromHls Error (\"$serverName - $typeName\"): $e") } -- 2.47.2 From 21f6e43e68985defae99fccb356c83b9a736d8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Franti=C5=A1ek=20Straka?= Date: Tue, 8 Apr 2025 14:39:50 +0200 Subject: [PATCH 04/13] longer delay --- .../eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt index 6de0a7f5..a7407881 100644 --- a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt +++ b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt @@ -589,7 +589,7 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { private const val PROXY_URL = "https://prox.aniplaynow.live" - private const val HEADERS_TIMEOUT_MINUTES = 15 + private const val HEADERS_TIMEOUT_MINUTES = 60 private val DATE_FORMATTER = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH) -- 2.47.2 From 07b02f4489e4ab138afb4aea1c87f63b3c6c5cf4 Mon Sep 17 00:00:00 2001 From: Arkai1 Date: Wed, 9 Apr 2025 22:51:52 +0530 Subject: [PATCH 05/13] Update MegaCloudExtractor.kt (#890) --- .../tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt b/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt index ead4b50b..d8cf24ab 100644 --- a/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt +++ b/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt @@ -141,7 +141,7 @@ class MegaCloudExtractor( } private fun getVideoDto(url: String): VideoDto { - val type = if (url.startsWith("https://megacloud.tv") or url.startsWith("https://megacloud.club")) 0 else 1 + val type = if (url.startsWith("https://megacloud.tv") or url.startsWith("https://megacloud.blog")) 0 else 1 val keyType = SOURCES_KEY[type] -- 2.47.2 From 4df27e22111e9da4a47e5afa5241045b29b5ffaf Mon Sep 17 00:00:00 2001 From: Zero <170967310+GraveEaterMadison@users.noreply.github.com> Date: Wed, 9 Apr 2025 22:57:31 +0530 Subject: [PATCH 06/13] Fix AnimePahe episode sorting and numbering logic (#881) * Fixed the episode number problem for animepahe * Changed hianime domain to hianime.bz * Bump AnimePahe extVersionCode to 30 for improved episode sorting and numbering * Update HiAnime.kt --------- Co-authored-by: GraveEaterMadison --- src/en/animepahe/build.gradle | 4 ++-- .../tachiyomi/animeextension/en/animepahe/AnimePahe.kt | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/en/animepahe/build.gradle b/src/en/animepahe/build.gradle index d2c0f169..2711909a 100644 --- a/src/en/animepahe/build.gradle +++ b/src/en/animepahe/build.gradle @@ -1,11 +1,11 @@ ext { extName = 'AnimePahe' extClass = '.AnimePahe' - extVersionCode = 29 + extVersionCode = 30 } apply from: "$rootDir/common.gradle" dependencies { implementation(libs.jsunpacker) -} \ No newline at end of file +} diff --git a/src/en/animepahe/src/eu/kanade/tachiyomi/animeextension/en/animepahe/AnimePahe.kt b/src/en/animepahe/src/eu/kanade/tachiyomi/animeextension/en/animepahe/AnimePahe.kt index c85d1679..98c11cd3 100644 --- a/src/en/animepahe/src/eu/kanade/tachiyomi/animeextension/en/animepahe/AnimePahe.kt +++ b/src/en/animepahe/src/eu/kanade/tachiyomi/animeextension/en/animepahe/AnimePahe.kt @@ -153,7 +153,15 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() { override fun episodeListParse(response: Response): List { val url = response.request.url.toString() val session = url.substringAfter("&id=").substringBefore("&") - return recursivePages(response, session) + val episodeList = recursivePages(response, session) + + return episodeList + .sortedBy { it.date_upload } // Optional, makes sure it's in correct order + .mapIndexed { index, episode -> + episode.episode_number = (index + 1).toFloat() + episode.name = "Episode ${index + 1}" + episode + } } private fun parseEpisodePage(episodes: List, animeSession: String): MutableList { -- 2.47.2 From f2cd1223b84311ae694ea6a29f22296649830b69 Mon Sep 17 00:00:00 2001 From: Arkai1 Date: Wed, 9 Apr 2025 22:57:44 +0530 Subject: [PATCH 07/13] Added 2025 and 2026 Year Filter for HiAnime and Aniplay (#891) * Update AniListFilters.kt * Update ZoroThemeFilters.kt * Update build.gradle.kts * Update build.gradle.kts --- lib-multisrc/anilist/build.gradle.kts | 2 +- .../src/eu/kanade/tachiyomi/multisrc/anilist/AniListFilters.kt | 2 ++ lib-multisrc/zorotheme/build.gradle.kts | 2 +- .../eu/kanade/tachiyomi/multisrc/zorotheme/ZoroThemeFilters.kt | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib-multisrc/anilist/build.gradle.kts b/lib-multisrc/anilist/build.gradle.kts index e2f11e9c..6e70fd15 100644 --- a/lib-multisrc/anilist/build.gradle.kts +++ b/lib-multisrc/anilist/build.gradle.kts @@ -2,4 +2,4 @@ plugins { id("lib-multisrc") } -baseVersionCode = 3 +baseVersionCode = 4 diff --git a/lib-multisrc/anilist/src/eu/kanade/tachiyomi/multisrc/anilist/AniListFilters.kt b/lib-multisrc/anilist/src/eu/kanade/tachiyomi/multisrc/anilist/AniListFilters.kt index 688d64e4..83b7b6dd 100644 --- a/lib-multisrc/anilist/src/eu/kanade/tachiyomi/multisrc/anilist/AniListFilters.kt +++ b/lib-multisrc/anilist/src/eu/kanade/tachiyomi/multisrc/anilist/AniListFilters.kt @@ -110,6 +110,8 @@ object AniListFilters { val YEAR_LIST = arrayOf( Pair("