AllAnime [EN]: Support mkissa stream encryption and move site domain to mkissa.to - #619
Conversation
9b858db to
430488c
Compare
430488c to
a1e03d4
Compare
Reviewer's GuideUpdates the AllAnime extension to work with mkissa.to’s new encrypted stream API by introducing an aaReq key manager/crypto helper, switching site domain and URLs, and refactoring video list fetching and decryption logic around the new scheme. Sequence diagram for AllAnime encrypted stream fetching with aaReqsequenceDiagram
actor User
participant AllAnime
participant AllAnimeKeyManager
participant AllAnimeCrypto
participant AllAnimeApi
User ->> AllAnime: getVideoList(episode)
AllAnime ->> AllAnime: fetchSourceUrls(episode)
loop up to MAX_KEY_ATTEMPTS
AllAnime ->> AllAnimeKeyManager: material(forceRefresh)
AllAnimeKeyManager ->> AllAnimeCrypto: deriveKey(mask, partB)
AllAnimeCrypto -->> AllAnimeKeyManager: SecretKeySpec
AllAnimeKeyManager -->> AllAnime: Material
AllAnime ->> AllAnimeKeyManager: aaReq(material)
AllAnimeKeyManager -->> AllAnime: aaReq token
AllAnime ->> AllAnimeApi: videoListRequest(episode, material)
AllAnimeApi -->> AllAnime: responseBody
alt encrypted payload present
AllAnime ->> AllAnimeKeyManager: decrypt(tobeparsed, material)
AllAnimeKeyManager ->> AllAnimeCrypto: decrypt(base64Payload, material.key)
AllAnimeCrypto -->> AllAnimeKeyManager: decrypted JSON
AllAnimeKeyManager -->> AllAnime: DecryptedEpisodeResult
else unencrypted and not isCryptoError(responseBody)
AllAnime -->> AllAnime: EpisodeResult
end
alt sourceUrls parsed
AllAnime -->> User: List<Video>
break exit loop
end
else isCryptoError(responseBody)
AllAnime ->> AllAnimeKeyManager: healMask()
AllAnimeKeyManager ->> AllAnimeCrypto: hexToBytesOrNull(hex)
AllAnimeCrypto -->> AllAnimeKeyManager: mask bytes
AllAnimeKeyManager -->> AllAnime: healed
end
AllAnime ->> AllAnimeKeyManager: invalidate()
end
AllAnime -->> User: error if no sourceUrls
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The override of
videoListRequest(episode: SEpisode)now throwsUnsupportedOperationException; if any existing code paths still call this method (e.g., external features or tooling expecting a request URL), consider either keeping a minimal implementation or documenting that it is intentionally unusable to avoid unexpected crashes. - In
AllAnimeKeyManager.resolveMask, thechunkBaseandappEntryUrlparsing rely on specificentry/app.*.jsand../chunks/*.jspatterns; consider adding a fallback or explicit error when these patterns fail to match, so future site changes surface a clear failure instead of silently preventing mask rotation healing.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The override of `videoListRequest(episode: SEpisode)` now throws `UnsupportedOperationException`; if any existing code paths still call this method (e.g., external features or tooling expecting a request URL), consider either keeping a minimal implementation or documenting that it is intentionally unusable to avoid unexpected crashes.
- In `AllAnimeKeyManager.resolveMask`, the `chunkBase` and `appEntryUrl` parsing rely on specific `entry/app.*.js` and `../chunks/*.js` patterns; consider adding a fallback or explicit error when these patterns fail to match, so future site changes surface a clear failure instead of silently preventing mask rotation healing.
## Individual Comments
### Comment 1
<location path="src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnime.kt" line_range="505-514" />
<code_context>
+ var lastError: Throwable? = null
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Error propagation in fetchSourceUrls can surface a misleading exception in mixed failure scenarios.
`lastError` is only updated on HTTP failures, not when decryption or JSON parsing fails. In a sequence where an initial network error is followed by decryption/parsing errors, the thrown exception will still be the network error, which misrepresents the latest failure. To keep the surfaced error aligned with the actual failure, update `lastError` on decryption/parsing errors as well, or track the failure reason per attempt and throw the most recent/most relevant one.
Suggested implementation:
```
private suspend fun fetchSourceUrls(episode: SEpisode): List<SourceUrl> {
var lastError: Throwable? = null
var maskHealed = false
repeat(MAX_KEY_ATTEMPTS) { attempt ->
var attemptError: Throwable? = null
val material = keyManager.material(forceRefresh = attempt > 0)
```
To fully implement the suggestion, you should also:
1. In the body of the `repeat(MAX_KEY_ATTEMPTS)` loop, set `attemptError` in *every* failure path, not just HTTP failures. For example:
- In the HTTP error catch block: `attemptError = httpException`.
- In the decryption error catch block: `attemptError = decryptionException`.
- In the JSON parsing error catch block: `attemptError = jsonException`.
2. After handling an attempt’s failure (inside the loop), assign `lastError = attemptError ?: lastError` so the most recent non-success attempt updates `lastError`.
3. Ensure that when the function finally throws after exhausting attempts, it throws `lastError` (or wraps it) so the surfaced exception corresponds to the last failure, regardless of whether it was HTTP, decryption, or parsing.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
Please Marge this to repo as fast as possible |
| // The site's default iframe host, for the legacy internal/player servers. | ||
| private const val PLAYER_DOMAIN = "https://allanime.day" |
There was a problem hiding this comment.
where does this come from, can't see it in the previously used code
There was a problem hiding this comment.
In the old code this host came from /getVersion, but that endpoint doesn't exist anymore, so it's hardcoded. allanime.day is the current player/clock host, and mkissa's own player still loads /player.html and /apivtwo/clock.json from there, so we're matching the site. It's only used by the internal servers, which from a quick look only show up on older titles like One Piece
|
@Red1tum overall, good work, tested and it works nicely, I'd be good if you can address the last sourcery comment |
|
@7heMech Fixed the sourcery comment. Also moved the API domain to |
great, merging soon |
|
@Red1tum Update the branch and bump version to 57. |
…allanime-mkissa-encryption # Conflicts: # src/en/allanime/build.gradle
|
@Alpha-782 Done |
Checklist:
extVersionCodevalue inbuild.gradlefor individual extensionsoverrideVersionCodeorbaseVersionCodeas needed for all multisrc extensionsisNsfw = trueflag inbuild.gradlewhen appropriateidif a source's name or language were changedweb_hi_res_512.pngwhen adding a new extensionCloses #607
AllAnime broke video playback after moving to mkissa and reworking how it serves stream sources. This updates the extension to fetch and decrypt sources the new way, and switches off the dead allmanga.to domain to mkissa.to.
Add a 👍 reaction to pull requests you find important.
Summary by Sourcery
Update the AllAnime extension to work with mkissa.to’s new encrypted stream API and updated site URLs.
New Features:
Bug Fixes:
Enhancements:
Build: