Skip to content

Jacket extraction may include random and tutorial #68

Open

Description

@283375

The current jacket extraction logic (ArcaeaPackageHelper) may include random and tutorial. Both exist in the APK under assets/songs/ but are not present in songlist. Worth investigating whether to exclude them.

Activity

  1. 283375 commented on Nov 13, 2026

    @283375
    CollaboratorAuthor

    /pi Check if this is true, and open a PR only if the fix is simple, otherwise report your findings here.

  2. github-actions commented on Nov 13, 2026

    @github-actions

    I'll investigate the jacket extraction logic and the actual APK contents.Now let me check the actual APK.Confirmed: exactly random and tutorial are the only extras.Confirmed. Now let me see where extracted jackets are consumed so the fix lands in the right place.The fix is a simple exclusion list. Let me also verify the partner icon side for a similar issue.Partner icons are IDs, so no comparable problem. The jacket fix is simple — I'll implement it.Now implement the fix:Now let me verify the change compiles and passes lint/format.Android deps need network. Let me try online.Compiles. Now open the PR.The push failed due to missing credentials in this environment, so I'll report the findings and the ready-to-apply change instead.

    Findings — confirmed ✅

    Verified against a real APK (v7.1.0c). Of the 562 assets/songs/<id>/ folders containing a file matching JACKET_FILENAME_REGEX, exactly two are not real songs and are absent from assets/songs/songlist:

    Folder Entry shipped
    assets/songs/random/ 1080_base.jpg
    assets/songs/tutorial/ base.jpg

    So apkJacketZipEntries() / extractJackets() do produce random.<ext> and tutorial.<ext> entries in the jacket hash database, which can never match a real chart.

    Partner icons are not affected: assets/char/ only contains NN[N]u?_icon.png entries, all numeric IDs — no equivalent non-song artifacts.

    The fix is simple, so it's implemented (but the PR could not be pushed)

    The change is 8 added lines / 1 removed in one file. git diff:

    --- a/app/src/main/java/xyz/sevive/arcaeaoffline/helpers/ArcaeaPackageHelper.kt
    +++ b/app/src/main/java/xyz/sevive/arcaeaoffline/helpers/ArcaeaPackageHelper.kt
    @@ -78,7 +78,8 @@ class ArcaeaPackageHelper(
             val tailFilename = Path(filenameParts.last()).name
             if (JACKET_FILENAME_REGEX.find(tailFilename) == null) return null
     
    -        val songId = filenameParts[filenameParts.size - 2].replace("dl_", "")
    +        val songId = filenameParts[filenameParts.size - 2].removePrefix("dl_")
    +        if (songId in JACKET_EXCLUDED_SONG_IDS) return null
     
             val path = Path(filename)
             val baseFilename = path.name.substringBeforeLast(".")
    @@ -281,6 +282,12 @@ class ArcaeaPackageHelper(
             const val APK_CHAR_FOLDER_ENTRY_NAME = "assets/char/"
     
             val JACKET_FILENAME_REGEX = """^(1080_)?(0|1|2|3|4|base)\.(jpg|png)$""".toRegex()
    +
    +        /**
    +         * Song folders shipped in the APK that are not real songs and do not appear in the songlist.
    +         * They provide placeholder jackets (`random`) and the tutorial background (`tutorial`).
    +         */
    +        val JACKET_EXCLUDED_SONG_IDS = setOf("random", "tutorial")
             val JACKET_RENAME_REGEX = """_.*$""".toRegex()
     
             val PARTNER_ICON_FILENAME_REGEX = """^\d+u?_icon\.(jpg|png)$""".toRegex()

    Why this placement: both apkJacketZipEntries() (used by ArcaeaResourcesStateHolder for the "jackets available" check) and extractJackets() funnel through jacketExtractFilename(), so filtering there covers both paths. .replace("dl_", "") was also tightened to .removePrefix("dl_") so only a leading prefix is stripped.

    Verification: ./gradlew :app:compileUnstableDebugKotlin and ./gradlew lintKotlin both pass.

    Blocker: git push failed with could not read Username for 'https://github.com', so no PR was created. The working tree at app/src/main/java/xyz/sevive/arcaeaoffline/helpers/ArcaeaPackageHelper.kt has the change applied — it just needs a branch/push with valid credentials. Suggested PR title: fix(resources): exclude random and tutorial from jacket extraction (Fixes #68).


    View action run | Model: deepseek/deepseek-flash | Time: 5m 59s | Tokens: 281.7K | Cost: $0.01 | Pi SDK v1.5.2 | Action v2.30.2-develop (develop @ c266065)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions