From 06eec89dfece214b7e19c2dbbbe3cb3b0daca821 Mon Sep 17 00:00:00 2001
From: raymonable <101374892+raymonable@users.noreply.github.com>
Date: Thu, 28 May 2026 14:51:41 -0400
Subject: [PATCH] fix: make minor rom versions always use the major rom key
---
docs/encryption.md | 4 ++--
.../samnyan/aqua/sega/general/filter/CompressionFilter.kt | 8 ++++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/docs/encryption.md b/docs/encryption.md
index 50437860..060cc1d3 100644
--- a/docs/encryption.md
+++ b/docs/encryption.md
@@ -15,7 +15,7 @@ Card Maker has encryption features in the client, but they are not supported due
```json
{
"code": "SDHD",
- "versions": [215, 216],
+ "versions": [215],
"key": "DECAFBADDECAFBADDECAFBADDECAFBADDECAFBADDECAFBADDECAFBADDECAFBAD",
"iv": "DECAFBADDECAFBADDECAFBADDECAFBAD",
"salt": "DECAFBADDECAFBAD",
@@ -27,7 +27,7 @@ Card Maker has encryption features in the client, but they are not supported due
Replace `code` with the correct code for your game (`SDHD` for Chunithm JP, `SDEZ` for Maimai JP, etc.).
Set `versions` to be an array of game versions without the decimal (215 for 2.15, 150 for 1.50, etc.).
-You MUST include rom patch versions in this array or it will not encrypt correctly.
+You must include the rom major version. Minor versions will automatically round down to use the major key.
- Maimai DX does NOT use iterations, you do not need to include it
- Ongeki always uses 64 iterations (you must include it)
diff --git a/src/main/java/icu/samnyan/aqua/sega/general/filter/CompressionFilter.kt b/src/main/java/icu/samnyan/aqua/sega/general/filter/CompressionFilter.kt
index 699315f4..7beb88ad 100644
--- a/src/main/java/icu/samnyan/aqua/sega/general/filter/CompressionFilter.kt
+++ b/src/main/java/icu/samnyan/aqua/sega/general/filter/CompressionFilter.kt
@@ -19,7 +19,7 @@ import java.util.*
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
-
+import kotlin.math.floor
/**
* @author samnyan (privateamusement@protonmail.com)
@@ -36,6 +36,10 @@ class CompressionFilter(
}
+ fun truncateVersion(version: Number): Number {
+ return floor(version.toFloat() / 5.0) * 5;
+ }
+
var keys = gameData.chu3GameEncryption + gameData.mai2GameEncryption + gameData.ogkGameEncryption
fun getEncryptionKeys(path: String): GameEncryptionKey? {
val endpoint = path.split("/").last()
@@ -43,7 +47,7 @@ class CompressionFilter(
val game = path.split("/")[2]
val version = path.split("/")[3].filterNot { it == '.' }.toInt()
- return keys.find { it.versions.contains(version) && it.code == game }
+ return keys.find { it.versions.contains(truncateVersion(version)) && it.code == game }
}
@OptIn(ExperimentalStdlibApi::class)